bitkeeper revision 1.1493 (428e623eLixPFfNTxCYBeRcapHg86g)
authoriap10@freefall.cl.cam.ac.uk <iap10@freefall.cl.cam.ac.uk>
Fri, 20 May 2005 22:18:38 +0000 (22:18 +0000)
committeriap10@freefall.cl.cam.ac.uk <iap10@freefall.cl.cam.ac.uk>
Fri, 20 May 2005 22:18:38 +0000 (22:18 +0000)
Merge freefall.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xen-2.0-testing.bk
into freefall.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xen-unstable.bk

28 files changed:
1  2 
.rootkeys
linux-2.4.30-xen-sparse/arch/xen/Makefile
linux-2.4.30-xen-sparse/arch/xen/config.in
linux-2.4.30-xen-sparse/arch/xen/defconfig-xen0
linux-2.4.30-xen-sparse/arch/xen/defconfig-xenU
linux-2.4.30-xen-sparse/arch/xen/drivers/blkif/frontend/vbd.c
linux-2.4.30-xen-sparse/arch/xen/kernel/Makefile
linux-2.4.30-xen-sparse/arch/xen/kernel/head.S
linux-2.4.30-xen-sparse/arch/xen/kernel/ldt.c
linux-2.4.30-xen-sparse/arch/xen/kernel/process.c
linux-2.4.30-xen-sparse/arch/xen/kernel/setup.c
linux-2.4.30-xen-sparse/arch/xen/kernel/traps.c
linux-2.4.30-xen-sparse/arch/xen/mm/fault.c
linux-2.4.30-xen-sparse/arch/xen/mm/init.c
linux-2.4.30-xen-sparse/arch/xen/mm/ioremap.c
linux-2.4.30-xen-sparse/include/asm-xen/desc.h
linux-2.4.30-xen-sparse/include/asm-xen/fixmap.h
linux-2.4.30-xen-sparse/include/asm-xen/mmu_context.h
linux-2.4.30-xen-sparse/include/asm-xen/page.h
linux-2.4.30-xen-sparse/include/asm-xen/pgalloc.h
linux-2.4.30-xen-sparse/include/asm-xen/pgtable-2level.h
linux-2.4.30-xen-sparse/include/asm-xen/pgtable.h
linux-2.4.30-xen-sparse/include/asm-xen/system.h
linux-2.4.30-xen-sparse/mkbuildtree
linux-2.4.30-xen-sparse/mm/highmem.c
linux-2.4.30-xen-sparse/mm/memory.c
linux-2.4.30-xen-sparse/mm/mremap.c
linux-2.6.11-xen-sparse/drivers/xen/blkfront/block.h

diff --cc .rootkeys
index 9c07e401ed0cb5e614861c8e2d4a0d58f3b128f0,b52fbc9e3a006c42142674dfa5453a1e81b161d9..a809c260c8eee46ff6721ba5bd8ea400c0c580c7
+++ b/.rootkeys
  423e7e8dVDL1WLfbmQWuXMbetYk4jA freebsd-5.3-xen-sparse/mkbuildtree
  423e7e8dBrOrAbydK6h49bY0VvDgPw freebsd-5.3-xen-sparse/xenfbsd_kernel_build
  4187ca95_eQN62ugV1zliQcfzXrHnw install.sh
- 3e5a4e6589G-U42lFKs43plskXoFxQ linux-2.4.29-xen-sparse/Makefile
- 3e5a4e65IEPjnWPZ5w3TxS5scV8Ewg linux-2.4.29-xen-sparse/arch/xen/Makefile
- 3e5a4e65n-KhsEAs-A4ULiStBp-r6w linux-2.4.29-xen-sparse/arch/xen/boot/Makefile
- 3e5a4e65OV_j_DBtjzt5vej771AJsA linux-2.4.29-xen-sparse/arch/xen/config.in
- 40648526SxcA4lGIHB_k7ID8VlRSzw linux-2.4.29-xen-sparse/arch/xen/defconfig-xen0
- 40c73c77QesbL7eIvG-fJGAtVwhGRg linux-2.4.29-xen-sparse/arch/xen/defconfig-xenU
- 3e6377f5xwPfYZkPHPrDbEq1PRN7uQ linux-2.4.29-xen-sparse/arch/xen/drivers/balloon/Makefile
- 4083dc16z0jvZEH4PiVDbDRreaNp6w linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/Makefile
- 4083dc16KQus88a4U3uCV6qVCA6_8Q linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/backend/Makefile
- 4075806dI5kfeMD5RV-DA0PYoThx_w linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/frontend/Makefile
- 4075806d4-j7vN0Mn0bklI1cRUX1vQ linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/frontend/common.h
- 4075806dibjCcfuXv6CINMhxWTw3jQ linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/frontend/vbd.c
- 3e5a4e65G3e2s0ghPMgiJ-gBTUJ0uQ linux-2.4.29-xen-sparse/arch/xen/drivers/console/Makefile
- 3e5a4e656nfFISThfbyXQOA6HN6YHw linux-2.4.29-xen-sparse/arch/xen/drivers/dom0/Makefile
- 40420a6ebRqDjufoN1WSJvolEW2Wjw linux-2.4.29-xen-sparse/arch/xen/drivers/evtchn/Makefile
- 4083dc16-Kd5y9psK_yk161sme5j5Q linux-2.4.29-xen-sparse/arch/xen/drivers/netif/Makefile
- 4083dc16UmHXxS9g_UFVnkUpN-oP2Q linux-2.4.29-xen-sparse/arch/xen/drivers/netif/backend/Makefile
- 405853f2wg7JXZJNltspMwOZJklxgw linux-2.4.29-xen-sparse/arch/xen/drivers/netif/frontend/Makefile
 +41ee5e8b_2rt-qHzbDXtIoBzOli0EA linux-2.4.29-xen-sparse/arch/xen/drivers/usbif/Makefile
 +41ee5e8bUhF4tH7OoJaVbUxdXqneVw linux-2.4.29-xen-sparse/arch/xen/drivers/usbif/backend/Makefile
 +41ee5e8bSPpxzhGO6TrY20TegW3cZg linux-2.4.29-xen-sparse/arch/xen/drivers/usbif/frontend/Makefile
- 3e5a4e65lWzkiPXsZdzPt2RNnJGG1g linux-2.4.29-xen-sparse/arch/xen/kernel/Makefile
- 3e5a4e65_hqfuxtGG8IUy6wRM86Ecg linux-2.4.29-xen-sparse/arch/xen/kernel/entry.S
- 3e5a4e65Hy_1iUvMTPsNqGNXd9uFpg linux-2.4.29-xen-sparse/arch/xen/kernel/head.S
- 3e5a4e65RMGcuA-HCn3-wNx3fFQwdg linux-2.4.29-xen-sparse/arch/xen/kernel/i386_ksyms.c
 +4241709bNBs1q4Ss32YW0CyFVOGhEg linux-2.4.29-xen-sparse/arch/xen/kernel/ioport.c
- 3e5a4e653U6cELGv528IxOLHvCq8iA linux-2.4.29-xen-sparse/arch/xen/kernel/irq.c
- 3e5a4e65muT6SU3ck47IP87Q7Ti5hA linux-2.4.29-xen-sparse/arch/xen/kernel/ldt.c
 +4270e964iKFC24KiVm6jC5Eo7MxV6w linux-2.4.29-xen-sparse/arch/xen/kernel/pci-dma.c
- 4051db95N9N99FjsRwi49YKUNHWI8A linux-2.4.29-xen-sparse/arch/xen/kernel/pci-pc.c
- 3e5a4e65IGt3WwQDNiL4h-gYWgNTWQ linux-2.4.29-xen-sparse/arch/xen/kernel/process.c
- 3e5a4e66tR-qJMLj3MppcKqmvuI2XQ linux-2.4.29-xen-sparse/arch/xen/kernel/setup.c
- 3e5a4e66fWSTagLGU2P8BGFGRjhDiw linux-2.4.29-xen-sparse/arch/xen/kernel/signal.c
- 3e5a4e66N__lUXNwzQ-eADRzK9LXuQ linux-2.4.29-xen-sparse/arch/xen/kernel/time.c
- 3e5a4e66aHCbQ_F5QZ8VeyikLmuRZQ linux-2.4.29-xen-sparse/arch/xen/kernel/traps.c
- 3e5a4e66-9_NczrVMbuQkoSLyXckIw linux-2.4.29-xen-sparse/arch/xen/lib/Makefile
- 3e5a4e6637ZDk0BvFEC-aFQs599-ng linux-2.4.29-xen-sparse/arch/xen/lib/delay.c
- 3e5a4e66croVgpcJyJuF2ycQw0HuJw linux-2.4.29-xen-sparse/arch/xen/mm/Makefile
- 3e5a4e66l8Q5Tv-6B3lQIRmaVbFPzg linux-2.4.29-xen-sparse/arch/xen/mm/fault.c
- 3e5a4e661gLzzff25pJooKIIWe7IWg linux-2.4.29-xen-sparse/arch/xen/mm/init.c
- 3f0bed43UUdQichXAiVNrjV-y2Kzcg linux-2.4.29-xen-sparse/arch/xen/mm/ioremap.c
- 3e5a4e66qRlSTcjafidMB6ulECADvg linux-2.4.29-xen-sparse/arch/xen/vmlinux.lds
- 3e5a4e66mrtlmV75L1tjKDg8RaM5gA linux-2.4.29-xen-sparse/drivers/block/ll_rw_blk.c
- 40d70c24-Dy2HUMrwSZagfXvAPnI4w linux-2.4.29-xen-sparse/drivers/char/Makefile
- 3f108aeaLcGDgQdFAANLTUEid0a05w linux-2.4.29-xen-sparse/drivers/char/mem.c
- 3e5a4e66rw65CxyolW9PKz4GG42RcA linux-2.4.29-xen-sparse/drivers/char/tty_io.c
- 40c9c0c1pPwYE3-4i-oI3ubUu7UgvQ linux-2.4.29-xen-sparse/drivers/scsi/aic7xxx/Makefile
 +41f97f64nW0wmgLxhwzPTzkF4E5ERA linux-2.4.29-xen-sparse/drivers/usb/hcd.c
- 3e5a4e66wbeCpsJgVf_U8Jde-CNcsA linux-2.4.29-xen-sparse/include/asm-xen/bugs.h
- 3e5a4e66HdSkvIV6SJ1evG_xmTmXHA linux-2.4.29-xen-sparse/include/asm-xen/desc.h
- 3e5a4e66SYp_UpAVcF8Lc1wa3Qtgzw linux-2.4.29-xen-sparse/include/asm-xen/fixmap.h
- 406aeeaaQvl4RNtmd9hDEugBURbFpQ linux-2.4.29-xen-sparse/include/asm-xen/highmem.h
- 3e5a4e67YtcyDLQsShhCfQwPSELfvA linux-2.4.29-xen-sparse/include/asm-xen/hw_irq.h
- 4060044fVx7-tokvNLKBf_6qBB4lqQ linux-2.4.29-xen-sparse/include/asm-xen/io.h
- 3e5a4e673p7PEOyHFm3nHkYX6HQYBg linux-2.4.29-xen-sparse/include/asm-xen/irq.h
- 40d70c240tW7TWArl1VUgIFH2nVO1A linux-2.4.29-xen-sparse/include/asm-xen/keyboard.h
- 3e5a4e678ddsQOpbSiRdy1GRcDc9WA linux-2.4.29-xen-sparse/include/asm-xen/mmu_context.h
- 40d06e5b2YWInUX1Xv9amVANwd_2Xg linux-2.4.29-xen-sparse/include/asm-xen/module.h
- 3e5a4e67mnQfh-R8KcQCaVo2Oho6yg linux-2.4.29-xen-sparse/include/asm-xen/page.h
- 409ba2e7ZfV5hqTvIzxLtpClnxtIzg linux-2.4.29-xen-sparse/include/asm-xen/pci.h
- 3e5a4e67uTYU5oEnIDjxuaez8njjqg linux-2.4.29-xen-sparse/include/asm-xen/pgalloc.h
- 3e5a4e67X7JyupgdYkgDX19Huj2sAw linux-2.4.29-xen-sparse/include/asm-xen/pgtable-2level.h
- 3e5a4e67gr4NLGtQ5CvSLimMYZlkOA linux-2.4.29-xen-sparse/include/asm-xen/pgtable.h
- 3e5a4e676uK4xErTBDH6XJREn9LSyg linux-2.4.29-xen-sparse/include/asm-xen/processor.h
- 41224663YBCUMX1kVo_HRUtgaHTi7w linux-2.4.29-xen-sparse/include/asm-xen/queues.h
- 3e5a4e68uJz-xI0IBVMD7xRLQKJDFg linux-2.4.29-xen-sparse/include/asm-xen/segment.h
- 3e5a4e68Nfdh6QcOKUTGCaYkf2LmYA linux-2.4.29-xen-sparse/include/asm-xen/smp.h
- 3e5a4e68mTr0zcp9SXDbnd-XLrrfxw linux-2.4.29-xen-sparse/include/asm-xen/system.h
- 3f1056a9L_kqHcFheV00KbKBzv9j5w linux-2.4.29-xen-sparse/include/asm-xen/vga.h
- 40659defgWA92arexpMGn8X3QMDj3w linux-2.4.29-xen-sparse/include/asm-xen/xor.h
- 3f056927gMHl7mWB89rb73JahbhQIA linux-2.4.29-xen-sparse/include/linux/blk.h
- 42305f54mFScQCttpj57EIm60BnxIg linux-2.4.29-xen-sparse/include/linux/highmem.h
- 419e0488SBzS3mdUhwgsES5a5e3abA linux-2.4.29-xen-sparse/include/linux/irq.h
- 4124f66fPHG6yvB_vXmesjvzrJ3yMg linux-2.4.29-xen-sparse/include/linux/mm.h
- 401c0590D_kwJDU59X8NyvqSv_Cl2A linux-2.4.29-xen-sparse/include/linux/sched.h
- 40a248afgI0_JKthdYAe8beVfXSTpQ linux-2.4.29-xen-sparse/include/linux/skbuff.h
- 401c0592pLrp_aCbQRo9GXiYQQaVVA linux-2.4.29-xen-sparse/include/linux/timer.h
- 3f9d4b44247udoqWEgFkaHiWv6Uvyg linux-2.4.29-xen-sparse/kernel/time.c
- 401c059bjLBFYHRD4Py2uM3eA1D4zQ linux-2.4.29-xen-sparse/kernel/timer.c
- 3e6e7c1efbQe93xCvOpOVCnXTMmQ5w linux-2.4.29-xen-sparse/mkbuildtree
- 406aeeafkrnCuIVWLFv3kfn4uAD5Eg linux-2.4.29-xen-sparse/mm/highmem.c
- 3e5a4e68GxCIaFH4sy01v1wjapetaA linux-2.4.29-xen-sparse/mm/memory.c
- 3f108af5VxPkLv13tXpXgoRKALQtXQ linux-2.4.29-xen-sparse/mm/mprotect.c
- 3e5a4e681xMPdF9xCMwpyfuYMySU5g linux-2.4.29-xen-sparse/mm/mremap.c
- 409ba2e7akOFqQUg6Qyg2s28xcXiMg linux-2.4.29-xen-sparse/mm/page_alloc.c
- 41505c57WAd5l1rlfCLNSCpx9J13vA linux-2.4.29-xen-sparse/net/core/skbuff.c
+ 3e5a4e6589G-U42lFKs43plskXoFxQ linux-2.4.30-xen-sparse/Makefile
+ 3e5a4e65IEPjnWPZ5w3TxS5scV8Ewg linux-2.4.30-xen-sparse/arch/xen/Makefile
+ 3e5a4e65n-KhsEAs-A4ULiStBp-r6w linux-2.4.30-xen-sparse/arch/xen/boot/Makefile
+ 3e5a4e65OV_j_DBtjzt5vej771AJsA linux-2.4.30-xen-sparse/arch/xen/config.in
+ 40648526SxcA4lGIHB_k7ID8VlRSzw linux-2.4.30-xen-sparse/arch/xen/defconfig-xen0
+ 40c73c77QesbL7eIvG-fJGAtVwhGRg linux-2.4.30-xen-sparse/arch/xen/defconfig-xenU
+ 3e6377f5xwPfYZkPHPrDbEq1PRN7uQ linux-2.4.30-xen-sparse/arch/xen/drivers/balloon/Makefile
+ 4083dc16z0jvZEH4PiVDbDRreaNp6w linux-2.4.30-xen-sparse/arch/xen/drivers/blkif/Makefile
+ 4083dc16KQus88a4U3uCV6qVCA6_8Q linux-2.4.30-xen-sparse/arch/xen/drivers/blkif/backend/Makefile
+ 4075806dI5kfeMD5RV-DA0PYoThx_w linux-2.4.30-xen-sparse/arch/xen/drivers/blkif/frontend/Makefile
+ 4075806d4-j7vN0Mn0bklI1cRUX1vQ linux-2.4.30-xen-sparse/arch/xen/drivers/blkif/frontend/common.h
+ 4075806dibjCcfuXv6CINMhxWTw3jQ linux-2.4.30-xen-sparse/arch/xen/drivers/blkif/frontend/vbd.c
+ 3e5a4e65G3e2s0ghPMgiJ-gBTUJ0uQ linux-2.4.30-xen-sparse/arch/xen/drivers/console/Makefile
+ 3e5a4e656nfFISThfbyXQOA6HN6YHw linux-2.4.30-xen-sparse/arch/xen/drivers/dom0/Makefile
+ 40420a6ebRqDjufoN1WSJvolEW2Wjw linux-2.4.30-xen-sparse/arch/xen/drivers/evtchn/Makefile
+ 4083dc16-Kd5y9psK_yk161sme5j5Q linux-2.4.30-xen-sparse/arch/xen/drivers/netif/Makefile
+ 4083dc16UmHXxS9g_UFVnkUpN-oP2Q linux-2.4.30-xen-sparse/arch/xen/drivers/netif/backend/Makefile
+ 405853f2wg7JXZJNltspMwOZJklxgw linux-2.4.30-xen-sparse/arch/xen/drivers/netif/frontend/Makefile
+ 3e5a4e65lWzkiPXsZdzPt2RNnJGG1g linux-2.4.30-xen-sparse/arch/xen/kernel/Makefile
+ 3e5a4e65_hqfuxtGG8IUy6wRM86Ecg linux-2.4.30-xen-sparse/arch/xen/kernel/entry.S
+ 3e5a4e65Hy_1iUvMTPsNqGNXd9uFpg linux-2.4.30-xen-sparse/arch/xen/kernel/head.S
+ 3e5a4e65RMGcuA-HCn3-wNx3fFQwdg linux-2.4.30-xen-sparse/arch/xen/kernel/i386_ksyms.c
+ 3e5a4e653U6cELGv528IxOLHvCq8iA linux-2.4.30-xen-sparse/arch/xen/kernel/irq.c
+ 3e5a4e65muT6SU3ck47IP87Q7Ti5hA linux-2.4.30-xen-sparse/arch/xen/kernel/ldt.c
+ 4051db95N9N99FjsRwi49YKUNHWI8A linux-2.4.30-xen-sparse/arch/xen/kernel/pci-pc.c
+ 3e5a4e65IGt3WwQDNiL4h-gYWgNTWQ linux-2.4.30-xen-sparse/arch/xen/kernel/process.c
+ 3e5a4e66tR-qJMLj3MppcKqmvuI2XQ linux-2.4.30-xen-sparse/arch/xen/kernel/setup.c
+ 3e5a4e66fWSTagLGU2P8BGFGRjhDiw linux-2.4.30-xen-sparse/arch/xen/kernel/signal.c
+ 3e5a4e66N__lUXNwzQ-eADRzK9LXuQ linux-2.4.30-xen-sparse/arch/xen/kernel/time.c
+ 3e5a4e66aHCbQ_F5QZ8VeyikLmuRZQ linux-2.4.30-xen-sparse/arch/xen/kernel/traps.c
+ 3e5a4e66-9_NczrVMbuQkoSLyXckIw linux-2.4.30-xen-sparse/arch/xen/lib/Makefile
+ 3e5a4e6637ZDk0BvFEC-aFQs599-ng linux-2.4.30-xen-sparse/arch/xen/lib/delay.c
+ 3e5a4e66croVgpcJyJuF2ycQw0HuJw linux-2.4.30-xen-sparse/arch/xen/mm/Makefile
+ 3e5a4e66l8Q5Tv-6B3lQIRmaVbFPzg linux-2.4.30-xen-sparse/arch/xen/mm/fault.c
+ 3e5a4e661gLzzff25pJooKIIWe7IWg linux-2.4.30-xen-sparse/arch/xen/mm/init.c
+ 3f0bed43UUdQichXAiVNrjV-y2Kzcg linux-2.4.30-xen-sparse/arch/xen/mm/ioremap.c
+ 3e5a4e66qRlSTcjafidMB6ulECADvg linux-2.4.30-xen-sparse/arch/xen/vmlinux.lds
+ 3e5a4e66mrtlmV75L1tjKDg8RaM5gA linux-2.4.30-xen-sparse/drivers/block/ll_rw_blk.c
+ 40d70c24-Dy2HUMrwSZagfXvAPnI4w linux-2.4.30-xen-sparse/drivers/char/Makefile
+ 3f108aeaLcGDgQdFAANLTUEid0a05w linux-2.4.30-xen-sparse/drivers/char/mem.c
+ 3e5a4e66rw65CxyolW9PKz4GG42RcA linux-2.4.30-xen-sparse/drivers/char/tty_io.c
+ 40c9c0c1pPwYE3-4i-oI3ubUu7UgvQ linux-2.4.30-xen-sparse/drivers/scsi/aic7xxx/Makefile
 -3e5a4e669uzIE54VwucPYtGwXLAbzA linux-2.4.30-xen-sparse/fs/exec.c
+ 3e5a4e66wbeCpsJgVf_U8Jde-CNcsA linux-2.4.30-xen-sparse/include/asm-xen/bugs.h
+ 3e5a4e66HdSkvIV6SJ1evG_xmTmXHA linux-2.4.30-xen-sparse/include/asm-xen/desc.h
+ 3e5a4e66SYp_UpAVcF8Lc1wa3Qtgzw linux-2.4.30-xen-sparse/include/asm-xen/fixmap.h
+ 406aeeaaQvl4RNtmd9hDEugBURbFpQ linux-2.4.30-xen-sparse/include/asm-xen/highmem.h
+ 3e5a4e67YtcyDLQsShhCfQwPSELfvA linux-2.4.30-xen-sparse/include/asm-xen/hw_irq.h
+ 4060044fVx7-tokvNLKBf_6qBB4lqQ linux-2.4.30-xen-sparse/include/asm-xen/io.h
+ 3e5a4e673p7PEOyHFm3nHkYX6HQYBg linux-2.4.30-xen-sparse/include/asm-xen/irq.h
+ 40d70c240tW7TWArl1VUgIFH2nVO1A linux-2.4.30-xen-sparse/include/asm-xen/keyboard.h
+ 3e5a4e678ddsQOpbSiRdy1GRcDc9WA linux-2.4.30-xen-sparse/include/asm-xen/mmu_context.h
+ 40d06e5b2YWInUX1Xv9amVANwd_2Xg linux-2.4.30-xen-sparse/include/asm-xen/module.h
 -3f8707e7ZmZ6TxyX0ZUEfvhA2Pb_xQ linux-2.4.30-xen-sparse/include/asm-xen/msr.h
+ 3e5a4e67mnQfh-R8KcQCaVo2Oho6yg linux-2.4.30-xen-sparse/include/asm-xen/page.h
+ 409ba2e7ZfV5hqTvIzxLtpClnxtIzg linux-2.4.30-xen-sparse/include/asm-xen/pci.h
+ 3e5a4e67uTYU5oEnIDjxuaez8njjqg linux-2.4.30-xen-sparse/include/asm-xen/pgalloc.h
+ 3e5a4e67X7JyupgdYkgDX19Huj2sAw linux-2.4.30-xen-sparse/include/asm-xen/pgtable-2level.h
+ 3e5a4e67gr4NLGtQ5CvSLimMYZlkOA linux-2.4.30-xen-sparse/include/asm-xen/pgtable.h
+ 3e5a4e676uK4xErTBDH6XJREn9LSyg linux-2.4.30-xen-sparse/include/asm-xen/processor.h
+ 41224663YBCUMX1kVo_HRUtgaHTi7w linux-2.4.30-xen-sparse/include/asm-xen/queues.h
+ 3e5a4e68uJz-xI0IBVMD7xRLQKJDFg linux-2.4.30-xen-sparse/include/asm-xen/segment.h
+ 3e5a4e68Nfdh6QcOKUTGCaYkf2LmYA linux-2.4.30-xen-sparse/include/asm-xen/smp.h
+ 3e5a4e68mTr0zcp9SXDbnd-XLrrfxw linux-2.4.30-xen-sparse/include/asm-xen/system.h
+ 3f1056a9L_kqHcFheV00KbKBzv9j5w linux-2.4.30-xen-sparse/include/asm-xen/vga.h
+ 40659defgWA92arexpMGn8X3QMDj3w linux-2.4.30-xen-sparse/include/asm-xen/xor.h
+ 3f056927gMHl7mWB89rb73JahbhQIA linux-2.4.30-xen-sparse/include/linux/blk.h
+ 42305f54mFScQCttpj57EIm60BnxIg linux-2.4.30-xen-sparse/include/linux/highmem.h
+ 419e0488SBzS3mdUhwgsES5a5e3abA linux-2.4.30-xen-sparse/include/linux/irq.h
+ 4124f66fPHG6yvB_vXmesjvzrJ3yMg linux-2.4.30-xen-sparse/include/linux/mm.h
+ 401c0590D_kwJDU59X8NyvqSv_Cl2A linux-2.4.30-xen-sparse/include/linux/sched.h
+ 40a248afgI0_JKthdYAe8beVfXSTpQ linux-2.4.30-xen-sparse/include/linux/skbuff.h
+ 401c0592pLrp_aCbQRo9GXiYQQaVVA linux-2.4.30-xen-sparse/include/linux/timer.h
+ 3f9d4b44247udoqWEgFkaHiWv6Uvyg linux-2.4.30-xen-sparse/kernel/time.c
+ 401c059bjLBFYHRD4Py2uM3eA1D4zQ linux-2.4.30-xen-sparse/kernel/timer.c
+ 3e6e7c1efbQe93xCvOpOVCnXTMmQ5w linux-2.4.30-xen-sparse/mkbuildtree
+ 406aeeafkrnCuIVWLFv3kfn4uAD5Eg linux-2.4.30-xen-sparse/mm/highmem.c
+ 3e5a4e68GxCIaFH4sy01v1wjapetaA linux-2.4.30-xen-sparse/mm/memory.c
+ 3f108af5VxPkLv13tXpXgoRKALQtXQ linux-2.4.30-xen-sparse/mm/mprotect.c
+ 3e5a4e681xMPdF9xCMwpyfuYMySU5g linux-2.4.30-xen-sparse/mm/mremap.c
+ 409ba2e7akOFqQUg6Qyg2s28xcXiMg linux-2.4.30-xen-sparse/mm/page_alloc.c
 -3e5a4e683HKVU-sxtagrDasRB8eBVw linux-2.4.30-xen-sparse/mm/swapfile.c
 -41180721bNns9Na7w1nJ0ZVt8bhUNA linux-2.4.30-xen-sparse/mm/vmalloc.c
+ 41505c57WAd5l1rlfCLNSCpx9J13vA linux-2.4.30-xen-sparse/net/core/skbuff.c
  40f562372u3A7_kfbYYixPHJJxYUxA linux-2.6.11-xen-sparse/arch/xen/Kconfig
  40f56237utH41NPukqHksuNf29IC9A linux-2.6.11-xen-sparse/arch/xen/Kconfig.drivers
  40f56237penAAlWVBVDpeQZNFIg8CA linux-2.6.11-xen-sparse/arch/xen/Makefile
index 0000000000000000000000000000000000000000,e8e161a3957547abe6bf2b154d2b3cc6007044dd..77da37bfaf485413f7a526f546b42e9fbcfb4813
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,137 +1,139 @@@
+ #
+ # xen/Makefile
+ #
+ # This file is included by the global makefile so that you can add your own
+ # architecture-specific flags and dependencies. Remember to do have actions
+ # for "archclean" and "archdep" for cleaning up and making dependencies for
+ # this architecture
+ #
+ # This file is subject to the terms and conditions of the GNU General Public
+ # License.  See the file "COPYING" in the main directory of this archive
+ # for more details.
+ #
+ # Copyright (C) 1994 by Linus Torvalds
+ #
+ # 19990713  Artur Skawina <skawina@geocities.com>
+ #           Added '-march' and '-mpreferred-stack-boundary' support
+ #
+ # If no .config file exists then use the appropriate defconfig-* file
+ ifneq (.config,$(wildcard .config))
+ DUMMYX:=$(shell cp $(TOPDIR)/arch/xen/defconfig$(EXTRAVERSION) $(TOPDIR)/.config)
+ -include $(TOPDIR)/.config
+ endif
+ LD=$(CROSS_COMPILE)ld -m elf_i386
+ OBJCOPY=$(CROSS_COMPILE)objcopy -R .note -R .comment -S
+ LDFLAGS=-e stext
+ LINKFLAGS =-T $(TOPDIR)/arch/xen/vmlinux.lds $(LDFLAGS)
+ CFLAGS += -pipe
+ check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi)
+ # prevent gcc from keeping the stack 16 byte aligned
+ CFLAGS += $(call check_gcc,-mpreferred-stack-boundary=2,)
+ ifdef CONFIG_M686
+ CFLAGS += -march=i686
+ endif
+ ifdef CONFIG_MPENTIUMIII
+ CFLAGS += -march=i686
+ endif
+ ifdef CONFIG_MPENTIUM4
+ CFLAGS += -march=i686
+ endif
+ ifdef CONFIG_MK7
+ CFLAGS += $(call check_gcc,-march=athlon,-march=i686 -malign-functions=4)
+ endif
+ # Disable unit-at-a-time mode, it makes gcc use a lot more stack
+ # due to the lack of sharing of stacklots.
+ CFLAGS += $(call check_gcc,-fno-unit-at-a-time,)
+ HEAD := arch/xen/kernel/head.o arch/xen/kernel/init_task.o
+ SUBDIRS += arch/xen/kernel arch/xen/mm arch/xen/lib
+ SUBDIRS += arch/xen/drivers/console 
+ SUBDIRS += arch/xen/drivers/evtchn
+ SUBDIRS += arch/xen/drivers/blkif
+ SUBDIRS += arch/xen/drivers/netif
++SUBDIRS += arch/xen/drivers/usbif
+ SUBDIRS += arch/xen/drivers/balloon
+ ifdef CONFIG_XEN_PRIVILEGED_GUEST
+ SUBDIRS += arch/xen/drivers/dom0 
+ endif
+ CORE_FILES += arch/xen/kernel/kernel.o arch/xen/mm/mm.o
+ CORE_FILES += arch/xen/drivers/evtchn/drv.o
+ CORE_FILES += arch/xen/drivers/console/drv.o
+ DRIVERS += arch/xen/drivers/blkif/drv.o
+ DRIVERS += arch/xen/drivers/netif/drv.o
++DRIVERS += arch/xen/drivers/usbif/drv.o
+ ifdef CONFIG_XEN_PRIVILEGED_GUEST
+ CORE_FILES += arch/xen/drivers/dom0/drv.o
+ endif
+ CORE_FILES += arch/xen/drivers/balloon/drv.o
+ LIBS := $(TOPDIR)/arch/xen/lib/lib.a $(LIBS) $(TOPDIR)/arch/xen/lib/lib.a
+ arch/xen/kernel: dummy
+       $(MAKE) linuxsubdirs SUBDIRS=arch/xen/kernel
+ arch/xen/mm: dummy
+       $(MAKE) linuxsubdirs SUBDIRS=arch/xen/mm
+ arch/xen/drivers/console: dummy
+       $(MAKE) linuxsubdirs SUBDIRS=arch/xen/drivers/console
+ arch/xen/drivers/network: dummy
+       $(MAKE) linuxsubdirs SUBDIRS=arch/xen/drivers/network
+ arch/xen/drivers/block: dummy
+       $(MAKE) linuxsubdirs SUBDIRS=arch/xen/drivers/block
+ arch/xen/drivers/dom0: dummy
+       $(MAKE) linuxsubdirs SUBDIRS=arch/xen/drivers/dom0
+ arch/xen/drivers/balloon: dummy
+       $(MAKE) linuxsubdirs SUBDIRS=arch/xen/drivers/balloon
+ MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+ vmlinux: arch/xen/vmlinux.lds
+ FORCE: ;
+ .PHONY: bzImage compressed clean archclean archmrproper archdep
+ bzImage: vmlinux
+       @$(MAKEBOOT) bzImage
+ INSTALL_NAME ?= $(KERNELRELEASE)
+ install: bzImage
+       mkdir -p $(INSTALL_PATH)/boot
+       ln -f -s vmlinuz-$(INSTALL_NAME)$(INSTALL_SUFFIX) $(INSTALL_PATH)/boot/vmlinuz-$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(XENGUEST)$(INSTALL_SUFFIX)
+       rm -f $(INSTALL_PATH)/boot/vmlinuz-$(INSTALL_NAME)$(INSTALL_SUFFIX)
+       install -m0644 arch/$(ARCH)/boot/bzImage $(INSTALL_PATH)/boot/vmlinuz-$(INSTALL_NAME)$(INSTALL_SUFFIX)
+       install -m0644 vmlinux $(INSTALL_PATH)/boot/vmlinux-syms-$(INSTALL_NAME)$(INSTALL_SUFFIX)
+       install -m0664 .config $(INSTALL_PATH)/boot/config-$(INSTALL_NAME)$(INSTALL_SUFFIX)
+       install -m0664 System.map $(INSTALL_PATH)/boot/System.map-$(INSTALL_NAME)$(INSTALL_SUFFIX)
+       ln -f -s vmlinuz-$(INSTALL_NAME)$(INSTALL_SUFFIX) $(INSTALL_PATH)/boot/vmlinuz-$(VERSION).$(PATCHLEVEL)$(XENGUEST)$(INSTALL_SUFFIX)
+ %_config: arch/xen/defconfig-%
+       rm -f .config arch/xen/defconfig
+       cp -f arch/xen/defconfig-$(@:_config=) arch/xen/defconfig
+       cp -f arch/xen/defconfig-$(@:_config=) .config
+ archclean:
+       @$(MAKEBOOT) clean
+ archmrproper:
+       rm -f include/asm-xen/xen-public/arch
+ archdep:
+       @$(MAKEBOOT) dep
index 0000000000000000000000000000000000000000,b69fbf5930900dece0b09dbe4a5759ea4b46fd12..23492fb5c8b853a759a1f9d9b91237fe922ca904
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,325 +1,337 @@@
 -if [ "$CONFIG_XEN_PHYSDEV_ACCESS" == "y" ]; then
+ #
+ # For a description of the syntax of this configuration file,
+ # see Documentation/kbuild/config-language.txt.
+ #
+ mainmenu_name "Linux Kernel Configuration"
+ define_bool CONFIG_XEN y
+ define_bool CONFIG_X86 y
+ define_bool CONFIG_ISA y
+ define_bool CONFIG_SBUS n
+ define_bool CONFIG_UID16 y
+ mainmenu_option next_comment
+ comment 'Xen'
+ bool 'Support for privileged operations (domain 0)' CONFIG_XEN_PRIVILEGED_GUEST
+ bool 'Device-driver domain (physical device access)' CONFIG_XEN_PHYSDEV_ACCESS
++if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then
++    bool 'USB-device backend driver' CONFIG_XEN_USB_BACKEND
++fi
+ bool 'Scrub memory before freeing it to Xen' CONFIG_XEN_SCRUB_PAGES
+ bool 'Network-device frontend driver' CONFIG_XEN_NETDEV_FRONTEND
+ bool 'Block-device frontend driver' CONFIG_XEN_BLKDEV_FRONTEND
++bool 'Block-device uses grant tables' CONFIG_XEN_BLKDEV_GRANT
++bool 'USB-device frontend driver' CONFIG_XEN_USB_FRONTEND
+ endmenu
+ # The IBM S/390 patch needs this.
+ define_bool CONFIG_NO_IDLE_HZ y
 -if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then
++if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then
+    define_bool CONFIG_FOREIGN_PAGES y
+ else
+    define_bool CONFIG_FOREIGN_PAGES n
+    define_bool CONFIG_NETDEVICES y
+    define_bool CONFIG_VT n
+ fi
+ mainmenu_option next_comment
+ comment 'Code maturity level options'
+ bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
+ endmenu
+ mainmenu_option next_comment
+ comment 'Loadable module support'
+ bool 'Enable loadable module support' CONFIG_MODULES
+ if [ "$CONFIG_MODULES" = "y" ]; then
+    bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
+    bool '  Kernel module loader' CONFIG_KMOD
+ fi
+ endmenu
+ mainmenu_option next_comment
+ comment 'Processor type and features'
+ choice 'Processor family' \
+       "Pentium-Pro/Celeron/Pentium-II         CONFIG_M686 \
+        Pentium-III/Celeron(Coppermine)        CONFIG_MPENTIUMIII \
+        Pentium-4                              CONFIG_MPENTIUM4 \
+        Athlon/Duron/K7                        CONFIG_MK7 \
+        Opteron/Athlon64/Hammer/K8             CONFIG_MK8 \
+        VIA-C3-2                               CONFIG_MVIAC3_2" Pentium-Pro
+    define_bool CONFIG_X86_WP_WORKS_OK y
+    define_bool CONFIG_X86_INVLPG y
+    define_bool CONFIG_X86_CMPXCHG y
+    define_bool CONFIG_X86_XADD y
+    define_bool CONFIG_X86_BSWAP y
+    define_bool CONFIG_X86_POPAD_OK y
+    define_bool CONFIG_RWSEM_GENERIC_SPINLOCK n
+    define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM y
+    define_bool CONFIG_X86_GOOD_APIC y
+    define_bool CONFIG_X86_PGE y
+    define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
+    define_bool CONFIG_X86_TSC y
+ if [ "$CONFIG_M686" = "y" ]; then
+    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
+ fi
+ if [ "$CONFIG_MPENTIUMIII" = "y" ]; then
+    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
+ fi
+ if [ "$CONFIG_MPENTIUM4" = "y" ]; then
+    define_int  CONFIG_X86_L1_CACHE_SHIFT 7
+ fi
+ if [ "$CONFIG_MK8" = "y" ]; then
+    define_bool CONFIG_MK7 y
+ fi
+ if [ "$CONFIG_MK7" = "y" ]; then
+    define_int  CONFIG_X86_L1_CACHE_SHIFT 6
+    define_bool CONFIG_X86_USE_3DNOW y
+ fi
+ if [ "$CONFIG_MVIAC3_2" = "y" ]; then
+    define_int  CONFIG_X86_L1_CACHE_SHIFT 5
+ fi
+ #if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+ #   tristate 'BIOS Enhanced Disk Drive calls determine boot disk (EXPERIMENTAL)' CONFIG_EDD
+ #fi
+ choice 'High Memory Support' \
+       "off    CONFIG_NOHIGHMEM \
+        4GB    CONFIG_HIGHMEM4G" off
+ #      64GB   CONFIG_HIGHMEM64G" off
+ if [ "$CONFIG_HIGHMEM4G" = "y" ]; then
+    define_bool CONFIG_HIGHMEM y
+ fi
+ if [ "$CONFIG_HIGHMEM64G" = "y" ]; then
+    define_bool CONFIG_HIGHMEM y
+    define_bool CONFIG_X86_PAE y
+ fi
+ if [ "$CONFIG_HIGHMEM" = "y" ]; then
+    bool 'HIGHMEM I/O support' CONFIG_HIGHIO
+ fi
+ define_int CONFIG_FORCE_MAX_ZONEORDER 11
+ #bool 'Symmetric multi-processing support' CONFIG_SMP
+ #if [ "$CONFIG_SMP" = "y" -a "$CONFIG_X86_CMPXCHG" = "y" ]; then
+ #   define_bool CONFIG_HAVE_DEC_LOCK y
+ #fi
+ endmenu
+ mainmenu_option next_comment
+ comment 'General setup'
+ bool 'Networking support' CONFIG_NET
+ if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then
+    bool 'PCI support' CONFIG_PCI
+    source drivers/pci/Config.in
+    bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG
+    if [ "$CONFIG_HOTPLUG" = "y" ] ; then
+       source drivers/pcmcia/Config.in
+       source drivers/hotplug/Config.in
+    else
+       define_bool CONFIG_PCMCIA n
+       define_bool CONFIG_HOTPLUG_PCI n
+    fi
+ fi
+ bool 'System V IPC' CONFIG_SYSVIPC
+ bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+ bool 'Sysctl support' CONFIG_SYSCTL
+ if [ "$CONFIG_PROC_FS" = "y" ]; then
+    choice 'Kernel core (/proc/kcore) format' \
+       "ELF            CONFIG_KCORE_ELF        \
+        A.OUT          CONFIG_KCORE_AOUT" ELF
+ fi
+ tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
+ bool 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
+ tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
+ bool 'Select task to kill on out of memory condition' CONFIG_OOM_KILLER
+ endmenu
+ if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then
+    source drivers/mtd/Config.in
+    source drivers/parport/Config.in
+    source drivers/pnp/Config.in
+    source drivers/block/Config.in
+    source drivers/md/Config.in
+ fi
+ if [ "$CONFIG_NET" = "y" ]; then
+    source net/Config.in
+ fi
+ if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then
+    mainmenu_option next_comment
+    comment 'ATA/IDE/MFM/RLL support'
+    tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
+    if [ "$CONFIG_IDE" != "n" ]; then
+       source drivers/ide/Config.in
+    else
+       define_bool CONFIG_BLK_DEV_HD n
+    fi
+    endmenu
+ fi
+ mainmenu_option next_comment
+ comment 'SCSI support'
+ tristate 'SCSI support' CONFIG_SCSI
+ if [ "$CONFIG_SCSI" != "n" ]; then
+    source drivers/scsi/Config.in
+ fi
+ endmenu
+ if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then
+    source drivers/message/fusion/Config.in
+    source drivers/ieee1394/Config.in
+    source drivers/message/i2o/Config.in
+    if [ "$CONFIG_NET" = "y" ]; then
+       mainmenu_option next_comment
+       comment 'Network device support'
+       bool 'Network device support' CONFIG_NETDEVICES
+       if [ "$CONFIG_NETDEVICES" = "y" ]; then
+          source drivers/net/Config.in
+          if [ "$CONFIG_ATM" = "y" -o "$CONFIG_ATM" = "m" ]; then
+             source drivers/atm/Config.in
+          fi
+       fi
+       endmenu
+    fi
+    source net/ax25/Config.in
+    source net/irda/Config.in
+    mainmenu_option next_comment
+    comment 'ISDN subsystem'
+    if [ "$CONFIG_NET" != "n" ]; then
+       tristate 'ISDN support' CONFIG_ISDN
+       if [ "$CONFIG_ISDN" != "n" ]; then
+          source drivers/isdn/Config.in
+       fi
+    fi
+    endmenu
+    if [ "$CONFIG_ISA" = "y" ]; then
+        mainmenu_option next_comment
+        comment 'Old CD-ROM drivers (not SCSI, not IDE)'
+    
+        bool 'Support non-SCSI/IDE/ATAPI CDROM drives' CONFIG_CD_NO_IDESCSI
+        if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
+           source drivers/cdrom/Config.in
+        fi
+        endmenu
+    fi
+    #
+    # input before char - char/joystick depends on it. As does USB.
+    #
+    source drivers/input/Config.in
+ else
+    #
+    # Block device driver configuration
+    #
+    mainmenu_option next_comment
+    comment 'Block devices'
+    tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP
+    dep_tristate 'Network block device support' CONFIG_BLK_DEV_NBD $CONFIG_NET
+    tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
+    if [ "$CONFIG_BLK_DEV_RAM" = "y" -o "$CONFIG_BLK_DEV_RAM" = "m" ]; then
+       int '  Default RAM disk size' CONFIG_BLK_DEV_RAM_SIZE 4096
+    fi
+    dep_bool '  Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD $CONFIG_BLK_DEV_RAM
+    bool 'Per partition statistics in /proc/partitions' CONFIG_BLK_STATS
+    define_bool CONFIG_BLK_DEV_HD n
+    endmenu
+ fi
+ source drivers/char/Config.in
++if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" -o "$CONFIG_XEN_USB_FRONTEND" = "y" ]; then
+    source drivers/media/Config.in
+ fi
+ source fs/Config.in
+ mainmenu_option next_comment
+ comment 'Console drivers'
+ define_bool CONFIG_XEN_CONSOLE y
+ if [ "$CONFIG_VT" = "y" ]; then
+    bool 'VGA text console' CONFIG_VGA_CONSOLE
+    bool 'Dummy console' CONFIG_DUMMY_CONSOLE 
+    if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then
+       bool 'Video mode selection support' CONFIG_VIDEO_SELECT
+       if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+          tristate 'MDA text console (dual-headed) (EXPERIMENTAL)' CONFIG_MDA_CONSOLE
+          source drivers/video/Config.in
+       fi
+    fi
+ fi
+ endmenu
+ if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then
+    mainmenu_option next_comment
+    comment 'Sound'
+    tristate 'Sound card support' CONFIG_SOUND
+    if [ "$CONFIG_SOUND" != "n" ]; then
+       source drivers/sound/Config.in
+    fi
+    endmenu
++fi
++if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" -o "$CONFIG_XEN_USB_FRONTEND" = "y" ]; then
++   if [ "$CONFIG_XEN_USB_FRONTEND" = "y" -o "$CONFIG_XEN_USB_BACKEND" = "y" ]; then
++       define_bool CONFIG_USB y
++   fi
+    source drivers/usb/Config.in
++fi
++if [ "$CONFIG_XEN_PHYSDEV_ACCESS" = "y" ]; then
+    source net/bluetooth/Config.in
+ fi
+ mainmenu_option next_comment
+ comment 'Kernel hacking'
+ bool 'Kernel debugging' CONFIG_DEBUG_KERNEL
+ if [ "$CONFIG_DEBUG_KERNEL" != "n" ]; then
+    bool '  Check for stack overflows' CONFIG_DEBUG_STACKOVERFLOW
+    bool '  Debug high memory support' CONFIG_DEBUG_HIGHMEM
+    bool '  Debug memory allocations' CONFIG_DEBUG_SLAB
+    bool '  Memory mapped I/O debugging' CONFIG_DEBUG_IOVIRT
+    bool '  Magic SysRq key' CONFIG_MAGIC_SYSRQ
+    bool '  Spinlock debugging' CONFIG_DEBUG_SPINLOCK
+    bool '  Verbose BUG() reporting (adds 70K)' CONFIG_DEBUG_BUGVERBOSE
+    bool '  Load all symbols for debugging' CONFIG_KALLSYMS
+    bool '  Compile the kernel with frame pointers' CONFIG_FRAME_POINTER
+ fi
+ int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0
+ endmenu
+ source crypto/Config.in
+ source lib/Config.in
index 0000000000000000000000000000000000000000,f9d953db6da33d112ee37b29f4a820f19db47d72..78e93e900b3aa88b00b8862b35d4f5b27457e01f
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,924 +1,927 @@@
+ #
+ # Automatically generated by make menuconfig: don't edit
+ #
+ CONFIG_XEN=y
+ CONFIG_X86=y
+ CONFIG_ISA=y
+ # CONFIG_SBUS is not set
+ CONFIG_UID16=y
+ #
+ # Xen
+ #
+ CONFIG_XEN_PRIVILEGED_GUEST=y
+ CONFIG_XEN_PHYSDEV_ACCESS=y
++# CONFIG_XEN_USB_BACKEND is not set
+ CONFIG_XEN_SCRUB_PAGES=y
+ CONFIG_XEN_NETDEV_FRONTEND=y
+ CONFIG_XEN_BLKDEV_FRONTEND=y
++CONFIG_XEN_BLKDEV_GRANT=y
++# CONFIG_XEN_USB_FRONTEND is not set
+ CONFIG_NO_IDLE_HZ=y
+ CONFIG_FOREIGN_PAGES=y
+ #
+ # Code maturity level options
+ #
+ CONFIG_EXPERIMENTAL=y
+ #
+ # Loadable module support
+ #
+ CONFIG_MODULES=y
+ CONFIG_MODVERSIONS=y
+ CONFIG_KMOD=y
+ #
+ # Processor type and features
+ #
+ CONFIG_M686=y
+ # CONFIG_MPENTIUMIII is not set
+ # CONFIG_MPENTIUM4 is not set
+ # CONFIG_MK7 is not set
+ # CONFIG_MK8 is not set
+ # CONFIG_MVIAC3_2 is not set
+ CONFIG_X86_WP_WORKS_OK=y
+ CONFIG_X86_INVLPG=y
+ CONFIG_X86_CMPXCHG=y
+ CONFIG_X86_XADD=y
+ CONFIG_X86_BSWAP=y
+ CONFIG_X86_POPAD_OK=y
+ # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+ CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+ CONFIG_X86_GOOD_APIC=y
+ CONFIG_X86_PGE=y
+ CONFIG_X86_USE_PPRO_CHECKSUM=y
+ CONFIG_X86_TSC=y
+ CONFIG_X86_L1_CACHE_SHIFT=5
+ CONFIG_NOHIGHMEM=y
+ # CONFIG_HIGHMEM4G is not set
+ CONFIG_FORCE_MAX_ZONEORDER=11
+ #
+ # General setup
+ #
+ CONFIG_NET=y
+ CONFIG_PCI=y
+ CONFIG_PCI_NAMES=y
+ CONFIG_HOTPLUG=y
+ #
+ # PCMCIA/CardBus support
+ #
+ # CONFIG_PCMCIA is not set
+ #
+ # PCI Hotplug Support
+ #
+ # CONFIG_HOTPLUG_PCI is not set
+ # CONFIG_HOTPLUG_PCI_COMPAQ is not set
+ # CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
+ # CONFIG_HOTPLUG_PCI_SHPC is not set
+ # CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set
+ # CONFIG_HOTPLUG_PCI_PCIE is not set
+ # CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
+ CONFIG_SYSVIPC=y
+ # CONFIG_BSD_PROCESS_ACCT is not set
+ CONFIG_SYSCTL=y
+ CONFIG_KCORE_ELF=y
+ # CONFIG_KCORE_AOUT is not set
+ CONFIG_BINFMT_AOUT=y
+ CONFIG_BINFMT_ELF=y
+ # CONFIG_BINFMT_MISC is not set
+ # CONFIG_OOM_KILLER is not set
+ #
+ # Memory Technology Devices (MTD)
+ #
+ # CONFIG_MTD is not set
+ #
+ # Parallel port support
+ #
+ # CONFIG_PARPORT is not set
+ #
+ # Plug and Play configuration
+ #
+ CONFIG_PNP=y
+ # CONFIG_ISAPNP is not set
+ #
+ # Block devices
+ #
+ # CONFIG_BLK_DEV_FD is not set
+ # CONFIG_BLK_DEV_XD is not set
+ # CONFIG_PARIDE is not set
+ # CONFIG_BLK_CPQ_DA is not set
+ # CONFIG_BLK_CPQ_CISS_DA is not set
+ # CONFIG_CISS_SCSI_TAPE is not set
+ # CONFIG_CISS_MONITOR_THREAD is not set
+ # CONFIG_BLK_DEV_DAC960 is not set
+ # CONFIG_BLK_DEV_UMEM is not set
+ # CONFIG_BLK_DEV_SX8 is not set
+ CONFIG_BLK_DEV_LOOP=y
+ CONFIG_BLK_DEV_NBD=y
+ CONFIG_BLK_DEV_RAM=y
+ CONFIG_BLK_DEV_RAM_SIZE=4096
+ CONFIG_BLK_DEV_INITRD=y
+ # CONFIG_BLK_STATS is not set
+ #
+ # Multi-device support (RAID and LVM)
+ #
+ CONFIG_MD=y
+ CONFIG_BLK_DEV_MD=y
+ CONFIG_MD_LINEAR=y
+ # CONFIG_MD_RAID0 is not set
+ CONFIG_MD_RAID1=y
+ # CONFIG_MD_RAID5 is not set
+ # CONFIG_MD_MULTIPATH is not set
+ CONFIG_BLK_DEV_LVM=y
+ #
+ # Networking options
+ #
+ CONFIG_PACKET=y
+ CONFIG_PACKET_MMAP=y
+ # CONFIG_NETLINK_DEV is not set
+ CONFIG_NETFILTER=y
+ # CONFIG_NETFILTER_DEBUG is not set
+ CONFIG_FILTER=y
+ CONFIG_UNIX=y
+ CONFIG_INET=y
+ # CONFIG_IP_MULTICAST is not set
+ # CONFIG_IP_ADVANCED_ROUTER is not set
+ CONFIG_IP_PNP=y
+ CONFIG_IP_PNP_DHCP=y
+ # CONFIG_IP_PNP_BOOTP is not set
+ # CONFIG_IP_PNP_RARP is not set
+ # CONFIG_NET_IPIP is not set
+ # CONFIG_NET_IPGRE is not set
+ # CONFIG_ARPD is not set
+ # CONFIG_INET_ECN is not set
+ # CONFIG_SYN_COOKIES is not set
+ #
+ #   IP: Netfilter Configuration
+ #
+ CONFIG_IP_NF_CONNTRACK=m
+ CONFIG_IP_NF_FTP=m
+ # CONFIG_IP_NF_AMANDA is not set
+ CONFIG_IP_NF_TFTP=m
+ CONFIG_IP_NF_IRC=m
+ # CONFIG_IP_NF_QUEUE is not set
+ CONFIG_IP_NF_IPTABLES=y
+ # CONFIG_IP_NF_MATCH_LIMIT is not set
+ # CONFIG_IP_NF_MATCH_MAC is not set
+ # CONFIG_IP_NF_MATCH_PKTTYPE is not set
+ # CONFIG_IP_NF_MATCH_MARK is not set
+ # CONFIG_IP_NF_MATCH_MULTIPORT is not set
+ # CONFIG_IP_NF_MATCH_TOS is not set
+ # CONFIG_IP_NF_MATCH_RECENT is not set
+ # CONFIG_IP_NF_MATCH_ECN is not set
+ # CONFIG_IP_NF_MATCH_DSCP is not set
+ # CONFIG_IP_NF_MATCH_AH_ESP is not set
+ # CONFIG_IP_NF_MATCH_LENGTH is not set
+ # CONFIG_IP_NF_MATCH_TTL is not set
+ # CONFIG_IP_NF_MATCH_TCPMSS is not set
+ # CONFIG_IP_NF_MATCH_HELPER is not set
+ CONFIG_IP_NF_MATCH_STATE=m
+ CONFIG_IP_NF_MATCH_CONNTRACK=m
+ # CONFIG_IP_NF_MATCH_UNCLEAN is not set
+ # CONFIG_IP_NF_MATCH_OWNER is not set
+ CONFIG_IP_NF_MATCH_PHYSDEV=y
+ CONFIG_IP_NF_FILTER=y
+ CONFIG_IP_NF_TARGET_REJECT=y
+ # CONFIG_IP_NF_TARGET_MIRROR is not set
+ CONFIG_IP_NF_NAT=m
+ CONFIG_IP_NF_NAT_NEEDED=y
+ CONFIG_IP_NF_TARGET_MASQUERADE=m
+ CONFIG_IP_NF_TARGET_REDIRECT=m
+ # CONFIG_IP_NF_NAT_SNMP_BASIC is not set
+ CONFIG_IP_NF_NAT_IRC=m
+ CONFIG_IP_NF_NAT_FTP=m
+ CONFIG_IP_NF_NAT_TFTP=m
+ # CONFIG_IP_NF_MANGLE is not set
+ CONFIG_IP_NF_TARGET_LOG=y
+ CONFIG_IP_NF_TARGET_ULOG=y
+ # CONFIG_IP_NF_TARGET_TCPMSS is not set
+ # CONFIG_IP_NF_ARPTABLES is not set
+ #
+ #   IP: Virtual Server Configuration
+ #
+ # CONFIG_IP_VS is not set
+ # CONFIG_IPV6 is not set
+ # CONFIG_KHTTPD is not set
+ #
+ #    SCTP Configuration (EXPERIMENTAL)
+ #
+ # CONFIG_IP_SCTP is not set
+ # CONFIG_ATM is not set
+ CONFIG_VLAN_8021Q=y
+ # CONFIG_IPX is not set
+ # CONFIG_ATALK is not set
+ # CONFIG_DECNET is not set
+ CONFIG_BRIDGE=y
+ CONFIG_BRIDGE_NF_EBTABLES=m
+ CONFIG_BRIDGE_EBT_T_FILTER=m
+ CONFIG_BRIDGE_EBT_T_NAT=m
+ CONFIG_BRIDGE_EBT_BROUTE=m
+ CONFIG_BRIDGE_EBT_LOG=m
+ CONFIG_BRIDGE_EBT_IPF=m
+ CONFIG_BRIDGE_EBT_ARPF=m
+ CONFIG_BRIDGE_EBT_AMONG=m
+ CONFIG_BRIDGE_EBT_LIMIT=m
+ CONFIG_BRIDGE_EBT_VLANF=m
+ CONFIG_BRIDGE_EBT_802_3=m
+ CONFIG_BRIDGE_EBT_PKTTYPE=m
+ CONFIG_BRIDGE_EBT_STP=m
+ CONFIG_BRIDGE_EBT_MARKF=m
+ CONFIG_BRIDGE_EBT_ARPREPLY=m
+ CONFIG_BRIDGE_EBT_SNAT=m
+ CONFIG_BRIDGE_EBT_DNAT=m
+ CONFIG_BRIDGE_EBT_REDIRECT=m
+ CONFIG_BRIDGE_EBT_MARK_T=m
+ # CONFIG_X25 is not set
+ # CONFIG_LAPB is not set
+ # CONFIG_LLC is not set
+ # CONFIG_NET_DIVERT is not set
+ # CONFIG_ECONET is not set
+ # CONFIG_WAN_ROUTER is not set
+ # CONFIG_NET_FASTROUTE is not set
+ # CONFIG_NET_HW_FLOWCONTROL is not set
+ #
+ # QoS and/or fair queueing
+ #
+ # CONFIG_NET_SCHED is not set
+ #
+ # Network testing
+ #
+ # CONFIG_NET_PKTGEN is not set
+ #
+ # ATA/IDE/MFM/RLL support
+ #
+ CONFIG_IDE=y
+ #
+ # IDE, ATA and ATAPI Block devices
+ #
+ CONFIG_BLK_DEV_IDE=y
+ # CONFIG_BLK_DEV_HD_IDE is not set
+ # CONFIG_BLK_DEV_HD is not set
+ # CONFIG_BLK_DEV_IDE_SATA is not set
+ CONFIG_BLK_DEV_IDEDISK=y
+ CONFIG_IDEDISK_MULTI_MODE=y
+ CONFIG_IDEDISK_STROKE=y
+ # CONFIG_BLK_DEV_IDECS is not set
+ # CONFIG_BLK_DEV_DELKIN is not set
+ CONFIG_BLK_DEV_IDECD=y
+ CONFIG_BLK_DEV_IDETAPE=y
+ CONFIG_BLK_DEV_IDEFLOPPY=y
+ CONFIG_BLK_DEV_IDESCSI=y
+ CONFIG_IDE_TASK_IOCTL=y
+ CONFIG_BLK_DEV_CMD640=y
+ CONFIG_BLK_DEV_CMD640_ENHANCED=y
+ # CONFIG_BLK_DEV_ISAPNP is not set
+ CONFIG_BLK_DEV_IDEPCI=y
+ CONFIG_BLK_DEV_GENERIC=y
+ CONFIG_IDEPCI_SHARE_IRQ=y
+ CONFIG_BLK_DEV_IDEDMA_PCI=y
+ CONFIG_BLK_DEV_OFFBOARD=y
+ # CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+ CONFIG_IDEDMA_PCI_AUTO=y
+ # CONFIG_IDEDMA_ONLYDISK is not set
+ CONFIG_BLK_DEV_IDEDMA=y
+ # CONFIG_IDEDMA_PCI_WIP is not set
+ CONFIG_BLK_DEV_ADMA100=y
+ CONFIG_BLK_DEV_AEC62XX=y
+ CONFIG_BLK_DEV_ALI15X3=y
+ CONFIG_WDC_ALI15X3=y
+ CONFIG_BLK_DEV_AMD74XX=y
+ CONFIG_AMD74XX_OVERRIDE=y
+ # CONFIG_BLK_DEV_ATIIXP is not set
+ CONFIG_BLK_DEV_CMD64X=y
+ CONFIG_BLK_DEV_TRIFLEX=y
+ CONFIG_BLK_DEV_CY82C693=y
+ CONFIG_BLK_DEV_CS5530=y
+ CONFIG_BLK_DEV_HPT34X=y
+ # CONFIG_HPT34X_AUTODMA is not set
+ CONFIG_BLK_DEV_HPT366=y
+ CONFIG_BLK_DEV_PIIX=y
+ CONFIG_BLK_DEV_NS87415=y
+ # CONFIG_BLK_DEV_OPTI621 is not set
+ CONFIG_BLK_DEV_PDC202XX_OLD=y
+ CONFIG_PDC202XX_BURST=y
+ CONFIG_BLK_DEV_PDC202XX_NEW=y
+ CONFIG_PDC202XX_FORCE=y
+ CONFIG_BLK_DEV_RZ1000=y
+ CONFIG_BLK_DEV_SC1200=y
+ CONFIG_BLK_DEV_SVWKS=y
+ CONFIG_BLK_DEV_SIIMAGE=y
+ CONFIG_BLK_DEV_SIS5513=y
+ CONFIG_BLK_DEV_SLC90E66=y
+ CONFIG_BLK_DEV_TRM290=y
+ CONFIG_BLK_DEV_VIA82CXXX=y
+ CONFIG_IDE_CHIPSETS=y
+ # CONFIG_BLK_DEV_4DRIVES is not set
+ # CONFIG_BLK_DEV_ALI14XX is not set
+ # CONFIG_BLK_DEV_DTC2278 is not set
+ # CONFIG_BLK_DEV_HT6560B is not set
+ # CONFIG_BLK_DEV_PDC4030 is not set
+ # CONFIG_BLK_DEV_QD65XX is not set
+ # CONFIG_BLK_DEV_UMC8672 is not set
+ CONFIG_IDEDMA_AUTO=y
+ # CONFIG_IDEDMA_IVB is not set
+ # CONFIG_DMA_NONPCI is not set
+ CONFIG_BLK_DEV_PDC202XX=y
+ # CONFIG_BLK_DEV_ATARAID is not set
+ # CONFIG_BLK_DEV_ATARAID_PDC is not set
+ # CONFIG_BLK_DEV_ATARAID_HPT is not set
+ # CONFIG_BLK_DEV_ATARAID_MEDLEY is not set
+ # CONFIG_BLK_DEV_ATARAID_SII is not set
+ #
+ # SCSI support
+ #
+ CONFIG_SCSI=y
+ CONFIG_BLK_DEV_SD=y
+ CONFIG_SD_EXTRA_DEVS=40
+ # CONFIG_CHR_DEV_ST is not set
+ # CONFIG_CHR_DEV_OSST is not set
+ # CONFIG_BLK_DEV_SR is not set
+ CONFIG_CHR_DEV_SG=y
+ # CONFIG_SCSI_DEBUG_QUEUES is not set
+ # CONFIG_SCSI_MULTI_LUN is not set
+ # CONFIG_SCSI_CONSTANTS is not set
+ # CONFIG_SCSI_LOGGING is not set
+ #
+ # SCSI low-level drivers
+ #
+ # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+ # CONFIG_SCSI_7000FASST is not set
+ # CONFIG_SCSI_ACARD is not set
+ # CONFIG_SCSI_AHA152X is not set
+ # CONFIG_SCSI_AHA1542 is not set
+ # CONFIG_SCSI_AHA1740 is not set
+ CONFIG_SCSI_AACRAID=y
+ CONFIG_SCSI_AIC7XXX=y
+ CONFIG_AIC7XXX_CMDS_PER_DEVICE=32
+ CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+ # CONFIG_AIC7XXX_PROBE_EISA_VL is not set
+ # CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
+ # CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+ CONFIG_AIC7XXX_DEBUG_MASK=0
+ # CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
+ CONFIG_SCSI_AIC79XX=y
+ CONFIG_AIC79XX_CMDS_PER_DEVICE=32
+ CONFIG_AIC79XX_RESET_DELAY_MS=15000
+ # CONFIG_AIC79XX_BUILD_FIRMWARE is not set
+ # CONFIG_AIC79XX_ENABLE_RD_STRM is not set
+ # CONFIG_AIC79XX_DEBUG_ENABLE is not set
+ CONFIG_AIC79XX_DEBUG_MASK=0
+ # CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
+ # CONFIG_SCSI_DPT_I2O is not set
+ # CONFIG_SCSI_ADVANSYS is not set
+ # CONFIG_SCSI_IN2000 is not set
+ # CONFIG_SCSI_AM53C974 is not set
+ CONFIG_SCSI_MEGARAID=y
+ # CONFIG_SCSI_MEGARAID2 is not set
+ CONFIG_SCSI_SATA=y
+ # CONFIG_SCSI_SATA_AHCI is not set
+ # CONFIG_SCSI_SATA_SVW is not set
+ CONFIG_SCSI_ATA_PIIX=y
+ # CONFIG_SCSI_SATA_NV is not set
+ # CONFIG_SCSI_SATA_QSTOR is not set
+ CONFIG_SCSI_SATA_PROMISE=y
+ CONFIG_SCSI_SATA_SX4=y
+ CONFIG_SCSI_SATA_SIL=y
+ CONFIG_SCSI_SATA_SIS=y
+ # CONFIG_SCSI_SATA_ULI is not set
+ CONFIG_SCSI_SATA_VIA=y
+ CONFIG_SCSI_SATA_VITESSE=y
+ CONFIG_SCSI_BUSLOGIC=y
+ # CONFIG_SCSI_OMIT_FLASHPOINT is not set
+ # CONFIG_SCSI_CPQFCTS is not set
+ # CONFIG_SCSI_DMX3191D is not set
+ # CONFIG_SCSI_DTC3280 is not set
+ # CONFIG_SCSI_EATA is not set
+ # CONFIG_SCSI_EATA_DMA is not set
+ # CONFIG_SCSI_EATA_PIO is not set
+ # CONFIG_SCSI_FUTURE_DOMAIN is not set
+ # CONFIG_SCSI_GDTH is not set
+ # CONFIG_SCSI_GENERIC_NCR5380 is not set
+ # CONFIG_SCSI_IPS is not set
+ # CONFIG_SCSI_INITIO is not set
+ # CONFIG_SCSI_INIA100 is not set
+ # CONFIG_SCSI_NCR53C406A is not set
+ # CONFIG_SCSI_NCR53C7xx is not set
+ CONFIG_SCSI_SYM53C8XX_2=y
+ CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
+ CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+ # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+ # CONFIG_SCSI_PAS16 is not set
+ # CONFIG_SCSI_PCI2000 is not set
+ # CONFIG_SCSI_PCI2220I is not set
+ # CONFIG_SCSI_PSI240I is not set
+ # CONFIG_SCSI_QLOGIC_FAS is not set
+ # CONFIG_SCSI_QLOGIC_ISP is not set
+ # CONFIG_SCSI_QLOGIC_FC is not set
+ # CONFIG_SCSI_QLOGIC_1280 is not set
+ # CONFIG_SCSI_SEAGATE is not set
+ # CONFIG_SCSI_SIM710 is not set
+ # CONFIG_SCSI_SYM53C416 is not set
+ # CONFIG_SCSI_DC390T is not set
+ # CONFIG_SCSI_T128 is not set
+ # CONFIG_SCSI_U14_34F is not set
+ # CONFIG_SCSI_ULTRASTOR is not set
+ # CONFIG_SCSI_NSP32 is not set
+ # CONFIG_SCSI_DEBUG is not set
+ #
+ # Fusion MPT device support
+ #
+ # CONFIG_FUSION is not set
+ # CONFIG_FUSION_BOOT is not set
+ # CONFIG_FUSION_ISENSE is not set
+ # CONFIG_FUSION_CTL is not set
+ # CONFIG_FUSION_LAN is not set
+ #
+ # IEEE 1394 (FireWire) support (EXPERIMENTAL)
+ #
+ # CONFIG_IEEE1394 is not set
+ #
+ # I2O device support
+ #
+ # CONFIG_I2O is not set
+ # CONFIG_I2O_PCI is not set
+ # CONFIG_I2O_BLOCK is not set
+ # CONFIG_I2O_LAN is not set
+ # CONFIG_I2O_SCSI is not set
+ # CONFIG_I2O_PROC is not set
+ #
+ # Network device support
+ #
+ CONFIG_NETDEVICES=y
+ #
+ # ARCnet devices
+ #
+ # CONFIG_ARCNET is not set
+ # CONFIG_DUMMY is not set
+ # CONFIG_BONDING is not set
+ # CONFIG_EQUALIZER is not set
+ # CONFIG_TUN is not set
+ # CONFIG_ETHERTAP is not set
+ #
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+ # CONFIG_SUNLANCE is not set
+ # CONFIG_HAPPYMEAL is not set
+ # CONFIG_SUNBMAC is not set
+ # CONFIG_SUNQE is not set
+ # CONFIG_SUNGEM is not set
+ CONFIG_NET_VENDOR_3COM=y
+ # CONFIG_EL1 is not set
+ # CONFIG_EL2 is not set
+ # CONFIG_ELPLUS is not set
+ # CONFIG_EL16 is not set
+ # CONFIG_EL3 is not set
+ # CONFIG_3C515 is not set
+ # CONFIG_ELMC is not set
+ # CONFIG_ELMC_II is not set
+ CONFIG_VORTEX=y
+ # CONFIG_TYPHOON is not set
+ # CONFIG_LANCE is not set
+ # CONFIG_NET_VENDOR_SMC is not set
+ # CONFIG_NET_VENDOR_RACAL is not set
+ # CONFIG_AT1700 is not set
+ # CONFIG_DEPCA is not set
+ # CONFIG_HP100 is not set
+ # CONFIG_NET_ISA is not set
+ CONFIG_NET_PCI=y
+ CONFIG_PCNET32=y
+ # CONFIG_AMD8111_ETH is not set
+ # CONFIG_ADAPTEC_STARFIRE is not set
+ # CONFIG_AC3200 is not set
+ # CONFIG_APRICOT is not set
+ # CONFIG_B44 is not set
+ # CONFIG_CS89x0 is not set
+ # CONFIG_TULIP is not set
+ # CONFIG_DE4X5 is not set
+ # CONFIG_DGRS is not set
+ # CONFIG_DM9102 is not set
+ # CONFIG_EEPRO100 is not set
+ # CONFIG_EEPRO100_PIO is not set
+ CONFIG_E100=y
+ # CONFIG_LNE390 is not set
+ # CONFIG_FEALNX is not set
+ # CONFIG_NATSEMI is not set
+ CONFIG_NE2K_PCI=y
+ # CONFIG_FORCEDETH is not set
+ # CONFIG_NE3210 is not set
+ # CONFIG_ES3210 is not set
+ # CONFIG_8139CP is not set
+ # CONFIG_8139TOO is not set
+ # CONFIG_8139TOO_PIO is not set
+ # CONFIG_8139TOO_TUNE_TWISTER is not set
+ # CONFIG_8139TOO_8129 is not set
+ # CONFIG_8139_OLD_RX_RESET is not set
+ # CONFIG_SIS900 is not set
+ # CONFIG_EPIC100 is not set
+ # CONFIG_SUNDANCE is not set
+ # CONFIG_SUNDANCE_MMIO is not set
+ # CONFIG_TLAN is not set
+ # CONFIG_VIA_RHINE is not set
+ # CONFIG_VIA_RHINE_MMIO is not set
+ # CONFIG_WINBOND_840 is not set
+ # CONFIG_NET_POCKET is not set
+ #
+ # Ethernet (1000 Mbit)
+ #
+ # CONFIG_ACENIC is not set
+ # CONFIG_DL2K is not set
+ CONFIG_E1000=y
+ # CONFIG_E1000_NAPI is not set
+ # CONFIG_MYRI_SBUS is not set
+ # CONFIG_NS83820 is not set
+ # CONFIG_HAMACHI is not set
+ # CONFIG_YELLOWFIN is not set
+ # CONFIG_R8169 is not set
+ # CONFIG_SK98LIN is not set
+ CONFIG_TIGON3=y
+ # CONFIG_FDDI is not set
+ # CONFIG_HIPPI is not set
+ # CONFIG_PLIP is not set
+ # CONFIG_PPP is not set
+ # CONFIG_SLIP is not set
+ #
+ # Wireless LAN (non-hamradio)
+ #
+ # CONFIG_NET_RADIO is not set
+ #
+ # Token Ring devices
+ #
+ # CONFIG_TR is not set
+ # CONFIG_NET_FC is not set
+ # CONFIG_RCPCI is not set
+ # CONFIG_SHAPER is not set
+ #
+ # Wan interfaces
+ #
+ # CONFIG_WAN is not set
+ #
+ # Amateur Radio support
+ #
+ # CONFIG_HAMRADIO is not set
+ #
+ # IrDA (infrared) support
+ #
+ # CONFIG_IRDA is not set
+ #
+ # ISDN subsystem
+ #
+ # CONFIG_ISDN is not set
+ #
+ # Old CD-ROM drivers (not SCSI, not IDE)
+ #
+ # CONFIG_CD_NO_IDESCSI is not set
+ #
+ # Input core support
+ #
+ # CONFIG_INPUT is not set
+ # CONFIG_INPUT_KEYBDEV is not set
+ # CONFIG_INPUT_MOUSEDEV is not set
+ # CONFIG_INPUT_JOYDEV is not set
+ # CONFIG_INPUT_EVDEV is not set
+ # CONFIG_INPUT_UINPUT is not set
+ #
+ # Character devices
+ #
+ CONFIG_VT=y
+ CONFIG_VT_CONSOLE=y
+ # CONFIG_SERIAL is not set
+ # CONFIG_SERIAL_EXTENDED is not set
+ # CONFIG_SERIAL_NONSTANDARD is not set
+ CONFIG_UNIX98_PTYS=y
+ CONFIG_UNIX98_PTY_COUNT=256
+ #
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+ #
+ # Mice
+ #
+ # CONFIG_BUSMOUSE is not set
+ CONFIG_MOUSE=y
+ CONFIG_PSMOUSE=y
+ # CONFIG_82C710_MOUSE is not set
+ # CONFIG_PC110_PAD is not set
+ # CONFIG_MK712_MOUSE is not set
+ #
+ # Joysticks
+ #
+ # CONFIG_INPUT_GAMEPORT is not set
+ # CONFIG_QIC02_TAPE is not set
+ # CONFIG_IPMI_HANDLER is not set
+ # CONFIG_IPMI_PANIC_EVENT is not set
+ # CONFIG_IPMI_DEVICE_INTERFACE is not set
+ # CONFIG_IPMI_KCS is not set
+ # CONFIG_IPMI_WATCHDOG is not set
+ #
+ # Watchdog Cards
+ #
+ # CONFIG_WATCHDOG is not set
+ # CONFIG_SCx200 is not set
+ # CONFIG_SCx200_GPIO is not set
+ # CONFIG_AMD_RNG is not set
+ # CONFIG_INTEL_RNG is not set
+ # CONFIG_HW_RANDOM is not set
+ # CONFIG_AMD_PM768 is not set
+ # CONFIG_NVRAM is not set
+ # CONFIG_RTC is not set
+ # CONFIG_DTLK is not set
+ # CONFIG_R3964 is not set
+ # CONFIG_APPLICOM is not set
+ # CONFIG_SONYPI is not set
+ #
+ # Ftape, the floppy tape device driver
+ #
+ # CONFIG_FTAPE is not set
+ # CONFIG_AGP is not set
+ #
+ # Direct Rendering Manager (XFree86 DRI support)
+ #
+ # CONFIG_DRM is not set
+ # CONFIG_MWAVE is not set
+ # CONFIG_OBMOUSE is not set
+ #
+ # Multimedia devices
+ #
+ # CONFIG_VIDEO_DEV is not set
+ #
+ # File systems
+ #
+ # CONFIG_QUOTA is not set
+ # CONFIG_QFMT_V2 is not set
+ CONFIG_AUTOFS_FS=y
+ CONFIG_AUTOFS4_FS=y
+ # CONFIG_REISERFS_FS is not set
+ # CONFIG_REISERFS_CHECK is not set
+ # CONFIG_REISERFS_PROC_INFO is not set
+ # CONFIG_ADFS_FS is not set
+ # CONFIG_ADFS_FS_RW is not set
+ # CONFIG_AFFS_FS is not set
+ # CONFIG_HFS_FS is not set
+ # CONFIG_HFSPLUS_FS is not set
+ # CONFIG_BEFS_FS is not set
+ # CONFIG_BEFS_DEBUG is not set
+ # CONFIG_BFS_FS is not set
+ CONFIG_EXT3_FS=y
+ CONFIG_JBD=y
+ # CONFIG_JBD_DEBUG is not set
+ CONFIG_FAT_FS=y
+ CONFIG_MSDOS_FS=y
+ CONFIG_UMSDOS_FS=y
+ CONFIG_VFAT_FS=y
+ # CONFIG_EFS_FS is not set
+ # CONFIG_JFFS_FS is not set
+ # CONFIG_JFFS2_FS is not set
+ # CONFIG_CRAMFS is not set
+ CONFIG_TMPFS=y
+ CONFIG_RAMFS=y
+ CONFIG_ISO9660_FS=y
+ CONFIG_JOLIET=y
+ CONFIG_ZISOFS=y
+ # CONFIG_JFS_FS is not set
+ # CONFIG_JFS_DEBUG is not set
+ # CONFIG_JFS_STATISTICS is not set
+ # CONFIG_MINIX_FS is not set
+ # CONFIG_VXFS_FS is not set
+ # CONFIG_NTFS_FS is not set
+ # CONFIG_NTFS_RW is not set
+ # CONFIG_HPFS_FS is not set
+ CONFIG_PROC_FS=y
+ # CONFIG_DEVFS_FS is not set
+ # CONFIG_DEVFS_MOUNT is not set
+ # CONFIG_DEVFS_DEBUG is not set
+ CONFIG_DEVPTS_FS=y
+ # CONFIG_QNX4FS_FS is not set
+ # CONFIG_QNX4FS_RW is not set
+ # CONFIG_ROMFS_FS is not set
+ CONFIG_EXT2_FS=y
+ # CONFIG_SYSV_FS is not set
+ # CONFIG_UDF_FS is not set
+ # CONFIG_UDF_RW is not set
+ # CONFIG_UFS_FS is not set
+ # CONFIG_UFS_FS_WRITE is not set
+ # CONFIG_XFS_FS is not set
+ # CONFIG_XFS_QUOTA is not set
+ # CONFIG_XFS_RT is not set
+ # CONFIG_XFS_TRACE is not set
+ # CONFIG_XFS_DEBUG is not set
+ #
+ # Network File Systems
+ #
+ # CONFIG_CODA_FS is not set
+ # CONFIG_INTERMEZZO_FS is not set
+ CONFIG_NFS_FS=y
+ CONFIG_NFS_V3=y
+ # CONFIG_NFS_DIRECTIO is not set
+ CONFIG_ROOT_NFS=y
+ CONFIG_NFSD=y
+ CONFIG_NFSD_V3=y
+ # CONFIG_NFSD_TCP is not set
+ CONFIG_SUNRPC=y
+ CONFIG_LOCKD=y
+ CONFIG_LOCKD_V4=y
+ # CONFIG_SMB_FS is not set
+ # CONFIG_NCP_FS is not set
+ # CONFIG_NCPFS_PACKET_SIGNING is not set
+ # CONFIG_NCPFS_IOCTL_LOCKING is not set
+ # CONFIG_NCPFS_STRONG is not set
+ # CONFIG_NCPFS_NFS_NS is not set
+ # CONFIG_NCPFS_OS2_NS is not set
+ # CONFIG_NCPFS_SMALLDOS is not set
+ # CONFIG_NCPFS_NLS is not set
+ # CONFIG_NCPFS_EXTRAS is not set
+ CONFIG_ZISOFS_FS=y
+ #
+ # Partition Types
+ #
+ CONFIG_PARTITION_ADVANCED=y
+ # CONFIG_ACORN_PARTITION is not set
+ # CONFIG_OSF_PARTITION is not set
+ # CONFIG_AMIGA_PARTITION is not set
+ # CONFIG_ATARI_PARTITION is not set
+ # CONFIG_MAC_PARTITION is not set
+ CONFIG_MSDOS_PARTITION=y
+ # CONFIG_BSD_DISKLABEL is not set
+ # CONFIG_MINIX_SUBPARTITION is not set
+ # CONFIG_SOLARIS_X86_PARTITION is not set
+ # CONFIG_UNIXWARE_DISKLABEL is not set
+ # CONFIG_LDM_PARTITION is not set
+ # CONFIG_SGI_PARTITION is not set
+ # CONFIG_ULTRIX_PARTITION is not set
+ # CONFIG_SUN_PARTITION is not set
+ # CONFIG_EFI_PARTITION is not set
+ # CONFIG_SMB_NLS is not set
+ CONFIG_NLS=y
+ #
+ # Native Language Support
+ #
+ CONFIG_NLS_DEFAULT="iso8559-1"
+ # CONFIG_NLS_CODEPAGE_437 is not set
+ # CONFIG_NLS_CODEPAGE_737 is not set
+ # CONFIG_NLS_CODEPAGE_775 is not set
+ # CONFIG_NLS_CODEPAGE_850 is not set
+ # CONFIG_NLS_CODEPAGE_852 is not set
+ # CONFIG_NLS_CODEPAGE_855 is not set
+ # CONFIG_NLS_CODEPAGE_857 is not set
+ # CONFIG_NLS_CODEPAGE_860 is not set
+ # CONFIG_NLS_CODEPAGE_861 is not set
+ # CONFIG_NLS_CODEPAGE_862 is not set
+ # CONFIG_NLS_CODEPAGE_863 is not set
+ # CONFIG_NLS_CODEPAGE_864 is not set
+ # CONFIG_NLS_CODEPAGE_865 is not set
+ # CONFIG_NLS_CODEPAGE_866 is not set
+ # CONFIG_NLS_CODEPAGE_869 is not set
+ # CONFIG_NLS_CODEPAGE_936 is not set
+ # CONFIG_NLS_CODEPAGE_950 is not set
+ # CONFIG_NLS_CODEPAGE_932 is not set
+ # CONFIG_NLS_CODEPAGE_949 is not set
+ # CONFIG_NLS_CODEPAGE_874 is not set
+ # CONFIG_NLS_ISO8859_8 is not set
+ # CONFIG_NLS_CODEPAGE_1250 is not set
+ # CONFIG_NLS_CODEPAGE_1251 is not set
+ CONFIG_NLS_ISO8859_1=y
+ # CONFIG_NLS_ISO8859_2 is not set
+ # CONFIG_NLS_ISO8859_3 is not set
+ # CONFIG_NLS_ISO8859_4 is not set
+ # CONFIG_NLS_ISO8859_5 is not set
+ # CONFIG_NLS_ISO8859_6 is not set
+ # CONFIG_NLS_ISO8859_7 is not set
+ # CONFIG_NLS_ISO8859_9 is not set
+ # CONFIG_NLS_ISO8859_13 is not set
+ # CONFIG_NLS_ISO8859_14 is not set
+ # CONFIG_NLS_ISO8859_15 is not set
+ # CONFIG_NLS_KOI8_R is not set
+ # CONFIG_NLS_KOI8_U is not set
+ # CONFIG_NLS_UTF8 is not set
+ #
+ # Console drivers
+ #
+ CONFIG_XEN_CONSOLE=y
+ CONFIG_VGA_CONSOLE=y
+ CONFIG_DUMMY_CONSOLE=y
+ # CONFIG_VIDEO_SELECT is not set
+ # CONFIG_MDA_CONSOLE is not set
+ #
+ # Frame-buffer support
+ #
+ # CONFIG_FB is not set
+ #
+ # Sound
+ #
+ # CONFIG_SOUND is not set
+ #
+ # USB support
+ #
+ # CONFIG_USB is not set
+ #
+ # Support for USB gadgets
+ #
+ # CONFIG_USB_GADGET is not set
+ #
+ # Bluetooth support
+ #
+ # CONFIG_BLUEZ is not set
+ #
+ # Kernel hacking
+ #
+ CONFIG_DEBUG_KERNEL=y
+ # CONFIG_DEBUG_STACKOVERFLOW is not set
+ # CONFIG_DEBUG_HIGHMEM is not set
+ # CONFIG_DEBUG_SLAB is not set
+ # CONFIG_DEBUG_IOVIRT is not set
+ # CONFIG_MAGIC_SYSRQ is not set
+ # CONFIG_DEBUG_SPINLOCK is not set
+ # CONFIG_DEBUG_BUGVERBOSE is not set
+ CONFIG_KALLSYMS=y
+ # CONFIG_FRAME_POINTER is not set
+ CONFIG_LOG_BUF_SHIFT=0
+ #
+ # Cryptographic options
+ #
+ CONFIG_CRYPTO=y
+ CONFIG_CRYPTO_HMAC=y
+ CONFIG_CRYPTO_NULL=m
+ CONFIG_CRYPTO_MD4=m
+ CONFIG_CRYPTO_MD5=m
+ CONFIG_CRYPTO_SHA1=m
+ CONFIG_CRYPTO_SHA256=m
+ CONFIG_CRYPTO_SHA512=m
+ # CONFIG_CRYPTO_WP512 is not set
+ CONFIG_CRYPTO_DES=m
+ CONFIG_CRYPTO_BLOWFISH=m
+ CONFIG_CRYPTO_TWOFISH=m
+ CONFIG_CRYPTO_SERPENT=m
+ CONFIG_CRYPTO_AES=m
+ CONFIG_CRYPTO_CAST5=m
+ CONFIG_CRYPTO_CAST6=m
+ # CONFIG_CRYPTO_TEA is not set
+ # CONFIG_CRYPTO_KHAZAD is not set
+ # CONFIG_CRYPTO_ANUBIS is not set
+ CONFIG_CRYPTO_ARC4=m
+ CONFIG_CRYPTO_DEFLATE=m
+ # CONFIG_CRYPTO_MICHAEL_MIC is not set
+ # CONFIG_CRYPTO_TEST is not set
+ #
+ # Library routines
+ #
+ # CONFIG_CRC32 is not set
+ CONFIG_ZLIB_INFLATE=y
+ CONFIG_ZLIB_DEFLATE=m
+ # CONFIG_FW_LOADER is not set
index 0000000000000000000000000000000000000000,9678a2c3fc30372f6f14e4339a7bc555d0dc7818..3640bfc19b3f6d1ea4afb300ad88bf84cac59a0a
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,560 +1,562 @@@
+ #
+ # Automatically generated make config: don't edit
+ #
+ CONFIG_XEN=y
+ CONFIG_X86=y
+ CONFIG_ISA=y
+ # CONFIG_SBUS is not set
+ CONFIG_UID16=y
+ #
+ # Xen
+ #
+ # CONFIG_XEN_PRIVILEGED_GUEST is not set
+ # CONFIG_XEN_PHYSDEV_ACCESS is not set
+ CONFIG_XEN_SCRUB_PAGES=y
+ CONFIG_XEN_NETDEV_FRONTEND=y
+ CONFIG_XEN_BLKDEV_FRONTEND=y
++CONFIG_XEN_BLKDEV_GRANT=y
++# CONFIG_XEN_USB_FRONTEND is not set
+ CONFIG_NO_IDLE_HZ=y
+ # CONFIG_FOREIGN_PAGES is not set
+ CONFIG_NETDEVICES=y
+ # CONFIG_VT is not set
+ #
+ # Code maturity level options
+ #
+ CONFIG_EXPERIMENTAL=y
+ #
+ # Loadable module support
+ #
+ CONFIG_MODULES=y
+ CONFIG_MODVERSIONS=y
+ CONFIG_KMOD=y
+ #
+ # Processor type and features
+ #
+ CONFIG_M686=y
+ # CONFIG_MPENTIUMIII is not set
+ # CONFIG_MPENTIUM4 is not set
+ # CONFIG_MK7 is not set
+ # CONFIG_MK8 is not set
+ # CONFIG_MVIAC3_2 is not set
+ CONFIG_X86_WP_WORKS_OK=y
+ CONFIG_X86_INVLPG=y
+ CONFIG_X86_CMPXCHG=y
+ CONFIG_X86_XADD=y
+ CONFIG_X86_BSWAP=y
+ CONFIG_X86_POPAD_OK=y
+ # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+ CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+ CONFIG_X86_GOOD_APIC=y
+ CONFIG_X86_PGE=y
+ CONFIG_X86_USE_PPRO_CHECKSUM=y
+ CONFIG_X86_TSC=y
+ CONFIG_X86_L1_CACHE_SHIFT=5
+ CONFIG_NOHIGHMEM=y
+ # CONFIG_HIGHMEM4G is not set
+ CONFIG_FORCE_MAX_ZONEORDER=11
+ #
+ # General setup
+ #
+ CONFIG_NET=y
+ CONFIG_SYSVIPC=y
+ # CONFIG_BSD_PROCESS_ACCT is not set
+ CONFIG_SYSCTL=y
+ CONFIG_KCORE_ELF=y
+ # CONFIG_KCORE_AOUT is not set
+ CONFIG_BINFMT_AOUT=y
+ CONFIG_BINFMT_ELF=y
+ # CONFIG_BINFMT_MISC is not set
+ # CONFIG_OOM_KILLER is not set
+ #
+ # Networking options
+ #
+ CONFIG_PACKET=y
+ CONFIG_PACKET_MMAP=y
+ # CONFIG_NETLINK_DEV is not set
+ CONFIG_NETFILTER=y
+ # CONFIG_NETFILTER_DEBUG is not set
+ CONFIG_FILTER=y
+ CONFIG_UNIX=y
+ CONFIG_INET=y
+ # CONFIG_IP_MULTICAST is not set
+ # CONFIG_IP_ADVANCED_ROUTER is not set
+ CONFIG_IP_PNP=y
+ CONFIG_IP_PNP_DHCP=y
+ # CONFIG_IP_PNP_BOOTP is not set
+ # CONFIG_IP_PNP_RARP is not set
+ # CONFIG_NET_IPIP is not set
+ # CONFIG_NET_IPGRE is not set
+ # CONFIG_ARPD is not set
+ # CONFIG_INET_ECN is not set
+ # CONFIG_SYN_COOKIES is not set
+ #
+ #   IP: Netfilter Configuration
+ #
+ CONFIG_IP_NF_CONNTRACK=y
+ CONFIG_IP_NF_FTP=y
+ # CONFIG_IP_NF_AMANDA is not set
+ CONFIG_IP_NF_TFTP=y
+ CONFIG_IP_NF_IRC=y
+ # CONFIG_IP_NF_QUEUE is not set
+ CONFIG_IP_NF_IPTABLES=y
+ # CONFIG_IP_NF_MATCH_LIMIT is not set
+ # CONFIG_IP_NF_MATCH_MAC is not set
+ # CONFIG_IP_NF_MATCH_PKTTYPE is not set
+ # CONFIG_IP_NF_MATCH_MARK is not set
+ # CONFIG_IP_NF_MATCH_MULTIPORT is not set
+ # CONFIG_IP_NF_MATCH_TOS is not set
+ # CONFIG_IP_NF_MATCH_RECENT is not set
+ # CONFIG_IP_NF_MATCH_ECN is not set
+ # CONFIG_IP_NF_MATCH_DSCP is not set
+ # CONFIG_IP_NF_MATCH_AH_ESP is not set
+ # CONFIG_IP_NF_MATCH_LENGTH is not set
+ # CONFIG_IP_NF_MATCH_TTL is not set
+ # CONFIG_IP_NF_MATCH_TCPMSS is not set
+ # CONFIG_IP_NF_MATCH_HELPER is not set
+ CONFIG_IP_NF_MATCH_STATE=y
+ CONFIG_IP_NF_MATCH_CONNTRACK=y
+ # CONFIG_IP_NF_MATCH_UNCLEAN is not set
+ # CONFIG_IP_NF_MATCH_OWNER is not set
+ CONFIG_IP_NF_FILTER=y
+ CONFIG_IP_NF_TARGET_REJECT=y
+ # CONFIG_IP_NF_TARGET_MIRROR is not set
+ CONFIG_IP_NF_NAT=y
+ CONFIG_IP_NF_NAT_NEEDED=y
+ CONFIG_IP_NF_TARGET_MASQUERADE=y
+ CONFIG_IP_NF_TARGET_REDIRECT=y
+ # CONFIG_IP_NF_NAT_SNMP_BASIC is not set
+ CONFIG_IP_NF_NAT_IRC=y
+ CONFIG_IP_NF_NAT_FTP=y
+ CONFIG_IP_NF_NAT_TFTP=y
+ # CONFIG_IP_NF_MANGLE is not set
+ CONFIG_IP_NF_TARGET_LOG=y
+ CONFIG_IP_NF_TARGET_ULOG=y
+ # CONFIG_IP_NF_TARGET_TCPMSS is not set
+ # CONFIG_IP_NF_ARPTABLES is not set
+ #
+ #   IP: Virtual Server Configuration
+ #
+ # CONFIG_IP_VS is not set
+ # CONFIG_IPV6 is not set
+ # CONFIG_KHTTPD is not set
+ #
+ #    SCTP Configuration (EXPERIMENTAL)
+ #
+ # CONFIG_IP_SCTP is not set
+ # CONFIG_ATM is not set
+ CONFIG_VLAN_8021Q=y
+ #
+ #  
+ #
+ # CONFIG_IPX is not set
+ # CONFIG_ATALK is not set
+ # CONFIG_DECNET is not set
+ # CONFIG_BRIDGE is not set
+ # CONFIG_X25 is not set
+ # CONFIG_LAPB is not set
+ # CONFIG_LLC is not set
+ # CONFIG_NET_DIVERT is not set
+ # CONFIG_ECONET is not set
+ # CONFIG_WAN_ROUTER is not set
+ # CONFIG_NET_FASTROUTE is not set
+ # CONFIG_NET_HW_FLOWCONTROL is not set
+ #
+ # QoS and/or fair queueing
+ #
+ # CONFIG_NET_SCHED is not set
+ #
+ # Network testing
+ #
+ # CONFIG_NET_PKTGEN is not set
+ #
+ # SCSI support
+ #
+ CONFIG_SCSI=y
+ #
+ # SCSI support type (disk, tape, CD-ROM)
+ #
+ CONFIG_BLK_DEV_SD=y
+ CONFIG_SD_EXTRA_DEVS=40
+ # CONFIG_CHR_DEV_ST is not set
+ # CONFIG_CHR_DEV_OSST is not set
+ # CONFIG_BLK_DEV_SR is not set
+ CONFIG_CHR_DEV_SG=y
+ #
+ # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+ #
+ # CONFIG_SCSI_DEBUG_QUEUES is not set
+ # CONFIG_SCSI_MULTI_LUN is not set
+ # CONFIG_SCSI_CONSTANTS is not set
+ # CONFIG_SCSI_LOGGING is not set
+ #
+ # SCSI low-level drivers
+ #
+ # CONFIG_SCSI_7000FASST is not set
+ # CONFIG_SCSI_ACARD is not set
+ # CONFIG_SCSI_AHA152X is not set
+ # CONFIG_SCSI_AHA1542 is not set
+ # CONFIG_SCSI_AHA1740 is not set
+ # CONFIG_SCSI_AACRAID is not set
+ # CONFIG_SCSI_AIC7XXX is not set
+ # CONFIG_SCSI_AIC79XX is not set
+ # CONFIG_SCSI_AIC7XXX_OLD is not set
+ # CONFIG_SCSI_DPT_I2O is not set
+ # CONFIG_SCSI_ADVANSYS is not set
+ # CONFIG_SCSI_IN2000 is not set
+ # CONFIG_SCSI_AM53C974 is not set
+ # CONFIG_SCSI_MEGARAID is not set
+ # CONFIG_SCSI_MEGARAID2 is not set
+ # CONFIG_SCSI_SATA is not set
+ # CONFIG_SCSI_SATA_AHCI is not set
+ # CONFIG_SCSI_SATA_SVW is not set
+ # CONFIG_SCSI_ATA_PIIX is not set
+ # CONFIG_SCSI_SATA_NV is not set
+ # CONFIG_SCSI_SATA_QSTOR is not set
+ # CONFIG_SCSI_SATA_PROMISE is not set
+ # CONFIG_SCSI_SATA_SX4 is not set
+ # CONFIG_SCSI_SATA_SIL is not set
+ # CONFIG_SCSI_SATA_SIS is not set
+ # CONFIG_SCSI_SATA_ULI is not set
+ # CONFIG_SCSI_SATA_VIA is not set
+ # CONFIG_SCSI_SATA_VITESSE is not set
+ # CONFIG_SCSI_BUSLOGIC is not set
+ # CONFIG_SCSI_DMX3191D is not set
+ # CONFIG_SCSI_DTC3280 is not set
+ # CONFIG_SCSI_EATA is not set
+ # CONFIG_SCSI_EATA_DMA is not set
+ # CONFIG_SCSI_EATA_PIO is not set
+ # CONFIG_SCSI_FUTURE_DOMAIN is not set
+ # CONFIG_SCSI_GDTH is not set
+ # CONFIG_SCSI_GENERIC_NCR5380 is not set
+ # CONFIG_SCSI_IPS is not set
+ # CONFIG_SCSI_INITIO is not set
+ # CONFIG_SCSI_INIA100 is not set
+ # CONFIG_SCSI_PPA is not set
+ # CONFIG_SCSI_IMM is not set
+ # CONFIG_SCSI_NCR53C406A is not set
+ # CONFIG_SCSI_NCR53C7xx is not set
+ # CONFIG_SCSI_PAS16 is not set
+ # CONFIG_SCSI_PCI2000 is not set
+ # CONFIG_SCSI_PCI2220I is not set
+ # CONFIG_SCSI_PSI240I is not set
+ # CONFIG_SCSI_QLOGIC_FAS is not set
+ # CONFIG_SCSI_SEAGATE is not set
+ # CONFIG_SCSI_SIM710 is not set
+ # CONFIG_SCSI_SYM53C416 is not set
+ # CONFIG_SCSI_T128 is not set
+ # CONFIG_SCSI_U14_34F is not set
+ # CONFIG_SCSI_ULTRASTOR is not set
+ # CONFIG_SCSI_NSP32 is not set
+ # CONFIG_SCSI_DEBUG is not set
+ #
+ # Block devices
+ #
+ CONFIG_BLK_DEV_LOOP=y
+ CONFIG_BLK_DEV_NBD=y
+ CONFIG_BLK_DEV_RAM=y
+ CONFIG_BLK_DEV_RAM_SIZE=4096
+ CONFIG_BLK_DEV_INITRD=y
+ # CONFIG_BLK_STATS is not set
+ # CONFIG_BLK_DEV_HD is not set
+ #
+ # Character devices
+ #
+ # CONFIG_VT is not set
+ # CONFIG_SERIAL is not set
+ # CONFIG_SERIAL_EXTENDED is not set
+ # CONFIG_SERIAL_NONSTANDARD is not set
+ CONFIG_UNIX98_PTYS=y
+ CONFIG_UNIX98_PTY_COUNT=256
+ # CONFIG_PRINTER is not set
+ # CONFIG_PPDEV is not set
+ # CONFIG_TIPAR is not set
+ #
+ # I2C support
+ #
+ # CONFIG_I2C is not set
+ #
+ # Mice
+ #
+ # CONFIG_BUSMOUSE is not set
+ CONFIG_MOUSE=y
+ CONFIG_PSMOUSE=y
+ # CONFIG_82C710_MOUSE is not set
+ # CONFIG_PC110_PAD is not set
+ # CONFIG_MK712_MOUSE is not set
+ #
+ # Joysticks
+ #
+ # CONFIG_INPUT_GAMEPORT is not set
+ # CONFIG_INPUT_NS558 is not set
+ # CONFIG_INPUT_LIGHTNING is not set
+ # CONFIG_INPUT_PCIGAME is not set
+ # CONFIG_INPUT_CS461X is not set
+ # CONFIG_INPUT_EMU10K1 is not set
+ # CONFIG_INPUT_SERIO is not set
+ # CONFIG_INPUT_SERPORT is not set
+ #
+ # Joysticks
+ #
+ # CONFIG_INPUT_ANALOG is not set
+ # CONFIG_INPUT_A3D is not set
+ # CONFIG_INPUT_ADI is not set
+ # CONFIG_INPUT_COBRA is not set
+ # CONFIG_INPUT_GF2K is not set
+ # CONFIG_INPUT_GRIP is not set
+ # CONFIG_INPUT_INTERACT is not set
+ # CONFIG_INPUT_TMDC is not set
+ # CONFIG_INPUT_SIDEWINDER is not set
+ # CONFIG_INPUT_IFORCE_USB is not set
+ # CONFIG_INPUT_IFORCE_232 is not set
+ # CONFIG_INPUT_WARRIOR is not set
+ # CONFIG_INPUT_MAGELLAN is not set
+ # CONFIG_INPUT_SPACEORB is not set
+ # CONFIG_INPUT_SPACEBALL is not set
+ # CONFIG_INPUT_STINGER is not set
+ # CONFIG_INPUT_DB9 is not set
+ # CONFIG_INPUT_GAMECON is not set
+ # CONFIG_INPUT_TURBOGRAFX is not set
+ # CONFIG_QIC02_TAPE is not set
+ # CONFIG_IPMI_HANDLER is not set
+ # CONFIG_IPMI_PANIC_EVENT is not set
+ # CONFIG_IPMI_DEVICE_INTERFACE is not set
+ # CONFIG_IPMI_KCS is not set
+ # CONFIG_IPMI_WATCHDOG is not set
+ #
+ # Watchdog Cards
+ #
+ # CONFIG_WATCHDOG is not set
+ # CONFIG_SCx200 is not set
+ # CONFIG_SCx200_GPIO is not set
+ # CONFIG_AMD_RNG is not set
+ # CONFIG_INTEL_RNG is not set
+ # CONFIG_HW_RANDOM is not set
+ # CONFIG_AMD_PM768 is not set
+ # CONFIG_NVRAM is not set
+ # CONFIG_RTC is not set
+ # CONFIG_DTLK is not set
+ # CONFIG_R3964 is not set
+ # CONFIG_APPLICOM is not set
+ # CONFIG_SONYPI is not set
+ #
+ # Ftape, the floppy tape device driver
+ #
+ # CONFIG_FTAPE is not set
+ # CONFIG_AGP is not set
+ #
+ # Direct Rendering Manager (XFree86 DRI support)
+ #
+ # CONFIG_DRM is not set
+ # CONFIG_MWAVE is not set
+ # CONFIG_OBMOUSE is not set
+ #
+ # File systems
+ #
+ # CONFIG_QUOTA is not set
+ # CONFIG_QFMT_V2 is not set
+ CONFIG_AUTOFS_FS=y
+ CONFIG_AUTOFS4_FS=y
+ # CONFIG_REISERFS_FS is not set
+ # CONFIG_REISERFS_CHECK is not set
+ # CONFIG_REISERFS_PROC_INFO is not set
+ # CONFIG_ADFS_FS is not set
+ # CONFIG_ADFS_FS_RW is not set
+ # CONFIG_AFFS_FS is not set
+ # CONFIG_HFS_FS is not set
+ # CONFIG_HFSPLUS_FS is not set
+ # CONFIG_BEFS_FS is not set
+ # CONFIG_BEFS_DEBUG is not set
+ # CONFIG_BFS_FS is not set
+ CONFIG_EXT3_FS=y
+ CONFIG_JBD=y
+ # CONFIG_JBD_DEBUG is not set
+ CONFIG_FAT_FS=y
+ CONFIG_MSDOS_FS=y
+ CONFIG_UMSDOS_FS=y
+ CONFIG_VFAT_FS=y
+ # CONFIG_EFS_FS is not set
+ # CONFIG_JFFS_FS is not set
+ # CONFIG_JFFS2_FS is not set
+ # CONFIG_CRAMFS is not set
+ CONFIG_TMPFS=y
+ CONFIG_RAMFS=y
+ CONFIG_ISO9660_FS=y
+ CONFIG_JOLIET=y
+ CONFIG_ZISOFS=y
+ # CONFIG_JFS_FS is not set
+ # CONFIG_JFS_DEBUG is not set
+ # CONFIG_JFS_STATISTICS is not set
+ # CONFIG_MINIX_FS is not set
+ # CONFIG_VXFS_FS is not set
+ # CONFIG_NTFS_FS is not set
+ # CONFIG_NTFS_RW is not set
+ # CONFIG_HPFS_FS is not set
+ CONFIG_PROC_FS=y
+ # CONFIG_DEVFS_FS is not set
+ # CONFIG_DEVFS_MOUNT is not set
+ # CONFIG_DEVFS_DEBUG is not set
+ CONFIG_DEVPTS_FS=y
+ # CONFIG_QNX4FS_FS is not set
+ # CONFIG_QNX4FS_RW is not set
+ # CONFIG_ROMFS_FS is not set
+ CONFIG_EXT2_FS=y
+ # CONFIG_SYSV_FS is not set
+ # CONFIG_UDF_FS is not set
+ # CONFIG_UDF_RW is not set
+ # CONFIG_UFS_FS is not set
+ # CONFIG_UFS_FS_WRITE is not set
+ # CONFIG_XFS_FS is not set
+ # CONFIG_XFS_QUOTA is not set
+ # CONFIG_XFS_RT is not set
+ # CONFIG_XFS_TRACE is not set
+ # CONFIG_XFS_DEBUG is not set
+ #
+ # Network File Systems
+ #
+ # CONFIG_CODA_FS is not set
+ # CONFIG_INTERMEZZO_FS is not set
+ CONFIG_NFS_FS=y
+ CONFIG_NFS_V3=y
+ # CONFIG_NFS_DIRECTIO is not set
+ CONFIG_ROOT_NFS=y
+ CONFIG_NFSD=y
+ CONFIG_NFSD_V3=y
+ # CONFIG_NFSD_TCP is not set
+ CONFIG_SUNRPC=y
+ CONFIG_LOCKD=y
+ CONFIG_LOCKD_V4=y
+ # CONFIG_SMB_FS is not set
+ # CONFIG_NCP_FS is not set
+ # CONFIG_NCPFS_PACKET_SIGNING is not set
+ # CONFIG_NCPFS_IOCTL_LOCKING is not set
+ # CONFIG_NCPFS_STRONG is not set
+ # CONFIG_NCPFS_NFS_NS is not set
+ # CONFIG_NCPFS_OS2_NS is not set
+ # CONFIG_NCPFS_SMALLDOS is not set
+ # CONFIG_NCPFS_NLS is not set
+ # CONFIG_NCPFS_EXTRAS is not set
+ CONFIG_ZISOFS_FS=y
+ #
+ # Partition Types
+ #
+ CONFIG_PARTITION_ADVANCED=y
+ # CONFIG_ACORN_PARTITION is not set
+ # CONFIG_OSF_PARTITION is not set
+ # CONFIG_AMIGA_PARTITION is not set
+ # CONFIG_ATARI_PARTITION is not set
+ # CONFIG_MAC_PARTITION is not set
+ CONFIG_MSDOS_PARTITION=y
+ # CONFIG_BSD_DISKLABEL is not set
+ # CONFIG_MINIX_SUBPARTITION is not set
+ # CONFIG_SOLARIS_X86_PARTITION is not set
+ # CONFIG_UNIXWARE_DISKLABEL is not set
+ # CONFIG_LDM_PARTITION is not set
+ # CONFIG_SGI_PARTITION is not set
+ # CONFIG_ULTRIX_PARTITION is not set
+ # CONFIG_SUN_PARTITION is not set
+ # CONFIG_EFI_PARTITION is not set
+ # CONFIG_SMB_NLS is not set
+ CONFIG_NLS=y
+ #
+ # Native Language Support
+ #
+ CONFIG_NLS_DEFAULT="iso8559-1"
+ # CONFIG_NLS_CODEPAGE_437 is not set
+ # CONFIG_NLS_CODEPAGE_737 is not set
+ # CONFIG_NLS_CODEPAGE_775 is not set
+ # CONFIG_NLS_CODEPAGE_850 is not set
+ # CONFIG_NLS_CODEPAGE_852 is not set
+ # CONFIG_NLS_CODEPAGE_855 is not set
+ # CONFIG_NLS_CODEPAGE_857 is not set
+ # CONFIG_NLS_CODEPAGE_860 is not set
+ # CONFIG_NLS_CODEPAGE_861 is not set
+ # CONFIG_NLS_CODEPAGE_862 is not set
+ # CONFIG_NLS_CODEPAGE_863 is not set
+ # CONFIG_NLS_CODEPAGE_864 is not set
+ # CONFIG_NLS_CODEPAGE_865 is not set
+ # CONFIG_NLS_CODEPAGE_866 is not set
+ # CONFIG_NLS_CODEPAGE_869 is not set
+ # CONFIG_NLS_CODEPAGE_936 is not set
+ # CONFIG_NLS_CODEPAGE_950 is not set
+ # CONFIG_NLS_CODEPAGE_932 is not set
+ # CONFIG_NLS_CODEPAGE_949 is not set
+ # CONFIG_NLS_CODEPAGE_874 is not set
+ # CONFIG_NLS_ISO8859_8 is not set
+ # CONFIG_NLS_CODEPAGE_1250 is not set
+ # CONFIG_NLS_CODEPAGE_1251 is not set
+ CONFIG_NLS_ISO8859_1=y
+ # CONFIG_NLS_ISO8859_2 is not set
+ # CONFIG_NLS_ISO8859_3 is not set
+ # CONFIG_NLS_ISO8859_4 is not set
+ # CONFIG_NLS_ISO8859_5 is not set
+ # CONFIG_NLS_ISO8859_6 is not set
+ # CONFIG_NLS_ISO8859_7 is not set
+ # CONFIG_NLS_ISO8859_9 is not set
+ # CONFIG_NLS_ISO8859_13 is not set
+ # CONFIG_NLS_ISO8859_14 is not set
+ # CONFIG_NLS_ISO8859_15 is not set
+ # CONFIG_NLS_KOI8_R is not set
+ # CONFIG_NLS_KOI8_U is not set
+ # CONFIG_NLS_UTF8 is not set
+ #
+ # Console drivers
+ #
+ CONFIG_XEN_CONSOLE=y
+ #
+ # Kernel hacking
+ #
+ CONFIG_DEBUG_KERNEL=y
+ # CONFIG_DEBUG_STACKOVERFLOW is not set
+ # CONFIG_DEBUG_HIGHMEM is not set
+ # CONFIG_DEBUG_SLAB is not set
+ # CONFIG_DEBUG_IOVIRT is not set
+ # CONFIG_MAGIC_SYSRQ is not set
+ # CONFIG_DEBUG_SPINLOCK is not set
+ # CONFIG_DEBUG_BUGVERBOSE is not set
+ CONFIG_KALLSYMS=y
+ # CONFIG_FRAME_POINTER is not set
+ CONFIG_LOG_BUF_SHIFT=0
+ #
+ # Cryptographic options
+ #
+ # CONFIG_CRYPTO is not set
+ #
+ # Library routines
+ #
+ # CONFIG_CRC32 is not set
+ CONFIG_ZLIB_INFLATE=y
+ # CONFIG_ZLIB_DEFLATE is not set
index 0000000000000000000000000000000000000000,d3f43f942647be85505a062e38eab690055392fb..682906bf66c0126103ba500f534cec39284aa7c9
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,564 +1,540 @@@
 -    /*
 -     * Update of partition info, and check of usage count, is protected
 -     * by the per-block-device semaphore.
 -     */
 -    down(&bd->bd_sem);
 -
+ /******************************************************************************
+  * arch/xen/drivers/blkif/frontend/vbd.c
+  * 
+  * Xenolinux virtual block-device driver.
+  * 
+  * Copyright (c) 2003-2004, Keir Fraser & Steve Hand
+  * Modifications by Mark A. Williamson are (c) Intel Research Cambridge
+  */
+ #include "common.h"
+ #include <linux/blk.h>
+ /*
+  * For convenience we distinguish between ide, scsi and 'other' (i.e.
+  * potentially combinations of the two) in the naming scheme and in a few 
+  * other places (like default readahead, etc).
+  */
+ #define XLIDE_MAJOR_NAME  "hd"
+ #define XLSCSI_MAJOR_NAME "sd"
+ #define XLVBD_MAJOR_NAME "xvd"
+ #define XLIDE_DEVS_PER_MAJOR   2
+ #define XLSCSI_DEVS_PER_MAJOR 16
+ #define XLVBD_DEVS_PER_MAJOR  16
+ #define XLIDE_PARTN_SHIFT  6    /* amount to shift minor to get 'real' minor */
+ #define XLIDE_MAX_PART    (1 << XLIDE_PARTN_SHIFT)     /* minors per ide vbd */
+ #define XLSCSI_PARTN_SHIFT 4    /* amount to shift minor to get 'real' minor */
+ #define XLSCSI_MAX_PART   (1 << XLSCSI_PARTN_SHIFT)   /* minors per scsi vbd */
+ #define XLVBD_PARTN_SHIFT  4    /* amount to shift minor to get 'real' minor */
+ #define XLVBD_MAX_PART    (1 << XLVBD_PARTN_SHIFT) /* minors per 'other' vbd */
+ /* The below are for the generic drivers/block/ll_rw_block.c code. */
+ static int xlide_blksize_size[256];
+ static int xlide_hardsect_size[256];
+ static int xlide_max_sectors[256];
+ static int xlscsi_blksize_size[256];
+ static int xlscsi_hardsect_size[256];
+ static int xlscsi_max_sectors[256];
+ static int xlvbd_blksize_size[256];
+ static int xlvbd_hardsect_size[256];
+ static int xlvbd_max_sectors[256];
+ /* Information about our VBDs. */
+ #define MAX_VBDS 64
+ static int nr_vbds;
+ static vdisk_t *vbd_info;
+ static struct block_device_operations xlvbd_block_fops = 
+ {
+     open:               blkif_open,
+     release:            blkif_release,
+     ioctl:              blkif_ioctl,
+     check_media_change: blkif_check,
+     revalidate:         blkif_revalidate,
+ };
+ static int xlvbd_get_vbd_info(vdisk_t *disk_info)
+ {
+     vdisk_t         *buf = (vdisk_t *)__get_free_page(GFP_KERNEL);
+     blkif_request_t  req;
+     blkif_response_t rsp;
+     int              nr;
+     memset(&req, 0, sizeof(req));
+     req.operation   = BLKIF_OP_PROBE;
+     req.nr_segments = 1;
++#ifdef CONFIG_XEN_BLKDEV_GRANT
++    blkif_control_probe_send(&req, &rsp,
++                             (unsigned long)(virt_to_machine(buf)));
++#else
+     req.frame_and_sects[0] = virt_to_machine(buf) | 7;
+     blkif_control_send(&req, &rsp);
++#endif
+     if ( rsp.status <= 0 )
+     {
+         printk(KERN_ALERT "Could not probe disks (%d)\n", rsp.status);
+         return -1;
+     }
+     if ( (nr = rsp.status) > MAX_VBDS )
+          nr = MAX_VBDS;
+     memcpy(disk_info, buf, nr * sizeof(vdisk_t));
+     return nr;
+ }
+ /*
+  * xlvbd_init_device - initialise a VBD device
+  * @disk:              a vdisk_t describing the VBD
+  *
+  * Takes a vdisk_t * that describes a VBD the domain has access to.
+  * Performs appropriate initialisation and registration of the device.
+  *
+  * Care needs to be taken when making re-entrant calls to ensure that
+  * corruption does not occur.  Also, devices that are in use should not have
+  * their details updated.  This is the caller's responsibility.
+  */
+ static int xlvbd_init_device(vdisk_t *xd)
+ {
+     int device = xd->device;
+     int major  = MAJOR(device); 
+     int minor  = MINOR(device);
+     int is_ide = IDE_DISK_MAJOR(major);  /* is this an ide device? */
+     int is_scsi= SCSI_BLK_MAJOR(major);  /* is this a scsi device? */
+     char *major_name;
+     struct gendisk *gd;
+     struct block_device *bd;
+     xl_disk_t *disk;
+     int i, rc = 0, max_part, partno;
+     unsigned long capacity;
+     unsigned char buf[64];
+     if ( (bd = bdget(device)) == NULL )
+         return -1;
 -    } else if (VDISK_VIRTUAL(xd->info)) {
 -
 -      major_name = XLVBD_MAJOR_NAME;
 -      max_part   = XLVBD_MAX_PART;
 -
+     if ( ((disk = xldev_to_xldisk(device)) != NULL) && (disk->usage != 0) )
+     {
+         printk(KERN_ALERT "VBD update failed - in use [dev=%x]\n", device);
+         rc = -1;
+         goto out;
+     }
+     if ( is_ide ) {
+       major_name = XLIDE_MAJOR_NAME; 
+       max_part   = XLIDE_MAX_PART;
+     } else if ( is_scsi ) {
+       major_name = XLSCSI_MAJOR_NAME;
+       max_part   = XLSCSI_MAX_PART;
 -    if ( VDISK_READONLY(xd->info) )
 -        set_device_ro(device, 1); 
+     } else { 
+         /* SMH: hmm - probably a CCISS driver or sim; assume CCISS for now */
+       printk(KERN_ALERT "Assuming device %02x:%02x is CCISS/SCSI\n", 
+              major, minor);
+       is_scsi    = 1; 
+       major_name = "cciss"; 
+       max_part   = XLSCSI_MAX_PART;
+     }
+     
+     partno = minor & (max_part - 1); 
+     
+     if ( (gd = get_gendisk(device)) == NULL )
+     {
+         rc = register_blkdev(major, major_name, &xlvbd_block_fops);
+         if ( rc < 0 )
+         {
+             printk(KERN_ALERT "XL VBD: can't get major %d\n", major);
+             goto out;
+         }
+         if ( is_ide )
+         { 
+             blksize_size[major]  = xlide_blksize_size;
+             hardsect_size[major] = xlide_hardsect_size;
+             max_sectors[major]   = xlide_max_sectors;
+             read_ahead[major]    = 8;
+         } 
+         else if ( is_scsi )
+         { 
+             blksize_size[major]  = xlscsi_blksize_size;
+             hardsect_size[major] = xlscsi_hardsect_size;
+             max_sectors[major]   = xlscsi_max_sectors;
+             read_ahead[major]    = 8;
+         }
+         else
+         { 
+             blksize_size[major]  = xlvbd_blksize_size;
+             hardsect_size[major] = xlvbd_hardsect_size;
+             max_sectors[major]   = xlvbd_max_sectors;
+             read_ahead[major]    = 8;
+         }
+         blk_init_queue(BLK_DEFAULT_QUEUE(major), do_blkif_request);
+         /*
+          * Turn off barking 'headactive' mode. We dequeue buffer heads as
+          * soon as we pass them to the back-end driver.
+          */
+         blk_queue_headactive(BLK_DEFAULT_QUEUE(major), 0);
+         /* Construct an appropriate gendisk structure. */
+         gd             = kmalloc(sizeof(struct gendisk), GFP_KERNEL);
+         gd->major      = major;
+         gd->major_name = major_name; 
+     
+         gd->max_p      = max_part; 
+         if ( is_ide )
+         { 
+             gd->minor_shift  = XLIDE_PARTN_SHIFT; 
+             gd->nr_real      = XLIDE_DEVS_PER_MAJOR; 
+         } 
+         else if ( is_scsi )
+         { 
+             gd->minor_shift  = XLSCSI_PARTN_SHIFT; 
+             gd->nr_real      = XLSCSI_DEVS_PER_MAJOR; 
+         }
+         else
+         { 
+             gd->minor_shift  = XLVBD_PARTN_SHIFT; 
+             gd->nr_real      = XLVBD_DEVS_PER_MAJOR; 
+         }
+         /* 
+         ** The sizes[] and part[] arrays hold the sizes and other 
+         ** information about every partition with this 'major' (i.e. 
+         ** every disk sharing the 8 bit prefix * max partns per disk) 
+         */
+         gd->sizes = kmalloc(max_part*gd->nr_real*sizeof(int), GFP_KERNEL);
+         gd->part  = kmalloc(max_part*gd->nr_real*sizeof(struct hd_struct), 
+                             GFP_KERNEL);
+         memset(gd->sizes, 0, max_part * gd->nr_real * sizeof(int));
+         memset(gd->part,  0, max_part * gd->nr_real 
+                * sizeof(struct hd_struct));
+         gd->real_devices = kmalloc(gd->nr_real * sizeof(xl_disk_t), 
+                                    GFP_KERNEL);
+         memset(gd->real_devices, 0, gd->nr_real * sizeof(xl_disk_t));
+         gd->next   = NULL;            
+         gd->fops   = &xlvbd_block_fops;
+         gd->de_arr = kmalloc(gd->nr_real * sizeof(*gd->de_arr), 
+                              GFP_KERNEL);
+         gd->flags  = kmalloc(gd->nr_real * sizeof(*gd->flags), GFP_KERNEL);
+     
+         memset(gd->de_arr, 0, gd->nr_real * sizeof(*gd->de_arr));
+         memset(gd->flags, 0, gd->nr_real *  sizeof(*gd->flags));
+         add_gendisk(gd);
+         blk_size[major] = gd->sizes;
+     }
 -        switch ( VDISK_TYPE(xd->info) )
++    if ( xd->info & VDISK_READONLY )
++        set_device_ro(device, 1);
+     gd->flags[minor >> gd->minor_shift] |= GENHD_FL_XEN;
+     /* NB. Linux 2.4 only handles 32-bit sector offsets and capacities. */
+     capacity = (unsigned long)xd->capacity;
+     if ( partno != 0 )
+     {
+         /*
+          * If this was previously set up as a real disc we will have set 
+          * up partition-table information. Virtual partitions override 
+          * 'real' partitions, and the two cannot coexist on a device.
+          */
+         if ( !(gd->flags[minor >> gd->minor_shift] & GENHD_FL_VIRT_PARTNS) &&
+              (gd->sizes[minor & ~(max_part-1)] != 0) )
+         {
+             /*
+              * Any non-zero sub-partition entries must be cleaned out before
+              * installing 'virtual' partition entries. The two types cannot
+              * coexist, and virtual partitions are favoured.
+              */
+             kdev_t dev = device & ~(max_part-1);
+             for ( i = max_part - 1; i > 0; i-- )
+             {
+                 invalidate_device(dev+i, 1);
+                 gd->part[MINOR(dev+i)].start_sect = 0;
+                 gd->part[MINOR(dev+i)].nr_sects   = 0;
+                 gd->sizes[MINOR(dev+i)]           = 0;
+             }
+             printk(KERN_ALERT
+                    "Virtual partitions found for /dev/%s - ignoring any "
+                    "real partition information we may have found.\n",
+                    disk_name(gd, MINOR(device), buf));
+         }
+         /* Need to skankily setup 'partition' information */
+         gd->part[minor].start_sect = 0; 
+         gd->part[minor].nr_sects   = capacity; 
+         gd->sizes[minor]           = capacity >>(BLOCK_SIZE_BITS-9); 
+         gd->flags[minor >> gd->minor_shift] |= GENHD_FL_VIRT_PARTNS;
+     }
+     else
+     {
+         gd->part[minor].nr_sects = capacity;
+         gd->sizes[minor] = capacity>>(BLOCK_SIZE_BITS-9);
+         
+         /* Some final fix-ups depending on the device type */
 -        case VDISK_TYPE_CDROM:
 -        case VDISK_TYPE_FLOPPY: 
 -        case VDISK_TYPE_TAPE:
++        if ( xd->info & VDISK_REMOVABLE )
+         { 
 -                   VDISK_TYPE(xd->info)==VDISK_TYPE_CDROM ? "cdrom" : 
 -                   (VDISK_TYPE(xd->info)==VDISK_TYPE_TAPE ? "tape" : 
 -                    "floppy"), disk_name(gd, MINOR(device), buf)); 
 -            break; 
 -
 -        case VDISK_TYPE_DISK:
+             gd->flags[minor >> gd->minor_shift] |= GENHD_FL_REMOVABLE; 
+             printk(KERN_ALERT 
+                    "Skipping partition check on %s /dev/%s\n", 
 -            break; 
 -
 -        default:
 -            printk(KERN_ALERT "XenoLinux: unknown device type %d\n", 
 -                   VDISK_TYPE(xd->info)); 
 -            break; 
++                   (xd->info & VDISK_CDROM) ? "cdrom" : "removable",
++                   disk_name(gd, MINOR(device), buf)); 
++        }
++        else
++        {
+             /* Only check partitions on real discs (not virtual!). */
+             if ( gd->flags[minor>>gd->minor_shift] & GENHD_FL_VIRT_PARTNS )
+             {
+                 printk(KERN_ALERT
+                        "Skipping partition check on virtual /dev/%s\n",
+                        disk_name(gd, MINOR(device), buf));
+                 break;
+             }
+             register_disk(gd, device, gd->max_p, &xlvbd_block_fops, capacity);
 -    up(&bd->bd_sem);
+         }
+     }
+  out:
 -    /*
 -     * Update of partition info, and check of usage count, is protected
 -     * by the per-block-device semaphore.
 -     */
 -    down(&bd->bd_sem);
 -
+     bdput(bd);    
+     return rc;
+ }
+ /*
+  * xlvbd_remove_device - remove a device node if possible
+  * @device:       numeric device ID
+  *
+  * Updates the gendisk structure and invalidates devices.
+  *
+  * This is OK for now but in future, should perhaps consider where this should
+  * deallocate gendisks / unregister devices.
+  */
+ static int xlvbd_remove_device(int device)
+ {
+     int i, rc = 0, minor = MINOR(device);
+     struct gendisk *gd;
+     struct block_device *bd;
+     xl_disk_t *disk = NULL;
+     if ( (bd = bdget(device)) == NULL )
+         return -1;
 -    up(&bd->bd_sem);
+     if ( ((gd = get_gendisk(device)) == NULL) ||
+          ((disk = xldev_to_xldisk(device)) == NULL) )
+         BUG();
+     if ( disk->usage != 0 )
+     {
+         printk(KERN_ALERT "VBD removal failed - in use [dev=%x]\n", device);
+         rc = -1;
+         goto out;
+     }
+  
+     if ( (minor & (gd->max_p-1)) != 0 )
+     {
+         /* 1: The VBD is mapped to a partition rather than a whole unit. */
+         invalidate_device(device, 1);
+       gd->part[minor].start_sect = 0;
+         gd->part[minor].nr_sects   = 0;
+         gd->sizes[minor]           = 0;
+         /* Clear the consists-of-virtual-partitions flag if possible. */
+         gd->flags[minor >> gd->minor_shift] &= ~GENHD_FL_VIRT_PARTNS;
+         for ( i = 1; i < gd->max_p; i++ )
+             if ( gd->sizes[(minor & ~(gd->max_p-1)) + i] != 0 )
+                 gd->flags[minor >> gd->minor_shift] |= GENHD_FL_VIRT_PARTNS;
+         /*
+          * If all virtual partitions are now gone, and a 'whole unit' VBD is
+          * present, then we can try to grok the unit's real partition table.
+          */
+         if ( !(gd->flags[minor >> gd->minor_shift] & GENHD_FL_VIRT_PARTNS) &&
+              (gd->sizes[minor & ~(gd->max_p-1)] != 0) &&
+              !(gd->flags[minor >> gd->minor_shift] & GENHD_FL_REMOVABLE) )
+         {
+             register_disk(gd,
+                           device&~(gd->max_p-1), 
+                           gd->max_p, 
+                           &xlvbd_block_fops,
+                           gd->part[minor&~(gd->max_p-1)].nr_sects);
+         }
+     }
+     else
+     {
+         /*
+          * 2: The VBD is mapped to an entire 'unit'. Clear all partitions.
+          * NB. The partition entries are only cleared if there are no VBDs
+          * mapped to individual partitions on this unit.
+          */
+         i = gd->max_p - 1; /* Default: clear subpartitions as well. */
+         if ( gd->flags[minor >> gd->minor_shift] & GENHD_FL_VIRT_PARTNS )
+             i = 0; /* 'Virtual' mode: only clear the 'whole unit' entry. */
+         while ( i >= 0 )
+         {
+             invalidate_device(device+i, 1);
+             gd->part[minor+i].start_sect = 0;
+             gd->part[minor+i].nr_sects   = 0;
+             gd->sizes[minor+i]           = 0;
+             i--;
+         }
+     }
+  out:
+     bdput(bd);
+     return rc;
+ }
+ /*
+  * xlvbd_update_vbds - reprobes the VBD status and performs updates driver
+  * state. The VBDs need to be updated in this way when the domain is
+  * initialised and also each time we receive an XLBLK_UPDATE event.
+  */
+ void xlvbd_update_vbds(void)
+ {
+     int i, j, k, old_nr, new_nr;
+     vdisk_t *old_info, *new_info, *merged_info;
+     old_info = vbd_info;
+     old_nr   = nr_vbds;
+     new_info = kmalloc(MAX_VBDS * sizeof(vdisk_t), GFP_KERNEL);
+     if (!new_info)
+         return;
+     if ( unlikely(new_nr = xlvbd_get_vbd_info(new_info)) < 0 )
+         goto out;
+     /*
+      * Final list maximum size is old list + new list. This occurs only when
+      * old list and new list do not overlap at all, and we cannot yet destroy
+      * VBDs in the old list because the usage counts are busy.
+      */
+     merged_info = kmalloc((old_nr + new_nr) * sizeof(vdisk_t), GFP_KERNEL);
+     if (!merged_info)
+         goto out;
+     /* @i tracks old list; @j tracks new list; @k tracks merged list. */
+     i = j = k = 0;
+     while ( (i < old_nr) && (j < new_nr) )
+     {
+         if ( old_info[i].device < new_info[j].device )
+         {
+             if ( xlvbd_remove_device(old_info[i].device) != 0 )
+                 memcpy(&merged_info[k++], &old_info[i], sizeof(vdisk_t));
+             i++;
+         }
+         else if ( old_info[i].device > new_info[j].device )
+         {
+             if ( xlvbd_init_device(&new_info[j]) == 0 )
+                 memcpy(&merged_info[k++], &new_info[j], sizeof(vdisk_t));
+             j++;
+         }
+         else
+         {
+             if ( ((old_info[i].capacity == new_info[j].capacity) &&
+                   (old_info[i].info == new_info[j].info)) ||
+                  (xlvbd_remove_device(old_info[i].device) != 0) )
+                 memcpy(&merged_info[k++], &old_info[i], sizeof(vdisk_t));
+             else if ( xlvbd_init_device(&new_info[j]) == 0 )
+                 memcpy(&merged_info[k++], &new_info[j], sizeof(vdisk_t));
+             i++; j++;
+         }
+     }
+     for ( ; i < old_nr; i++ )
+     {
+         if ( xlvbd_remove_device(old_info[i].device) != 0 )
+             memcpy(&merged_info[k++], &old_info[i], sizeof(vdisk_t));
+     }
+     for ( ; j < new_nr; j++ )
+     {
+         if ( xlvbd_init_device(&new_info[j]) == 0 )
+             memcpy(&merged_info[k++], &new_info[j], sizeof(vdisk_t));
+     }
+     vbd_info = merged_info;
+     nr_vbds  = k;
+     kfree(old_info);
+ out:
+     kfree(new_info);
+ }
+ /*
+  * Set up all the linux device goop for the virtual block devices (vbd's) that
+  * we know about. Note that although from the backend driver's p.o.v. VBDs are
+  * addressed simply an opaque 16-bit device number, the domain creation tools 
+  * conventionally allocate these numbers to correspond to those used by 'real' 
+  * linux -- this is just for convenience as it means e.g. that the same 
+  * /etc/fstab can be used when booting with or without Xen.
+  */
+ int xlvbd_init(void)
+ {
+     int i;
+     
+     /*
+      * If compiled as a module, we don't support unloading yet. We therefore 
+      * permanently increment the reference count to disallow it.
+      */
+     SET_MODULE_OWNER(&xlvbd_block_fops);
+     MOD_INC_USE_COUNT;
+     /* Initialize the global arrays. */
+     for ( i = 0; i < 256; i++ ) 
+     {
+         xlide_blksize_size[i]  = 1024;
+         xlide_hardsect_size[i] = 512;
+         xlide_max_sectors[i]   = 512;
+         xlscsi_blksize_size[i]  = 1024;
+         xlscsi_hardsect_size[i] = 512;
+         xlscsi_max_sectors[i]   = 512;
+         xlvbd_blksize_size[i]  = 512;
+         xlvbd_hardsect_size[i] = 512;
+         xlvbd_max_sectors[i]   = 512;
+     }
+     vbd_info = kmalloc(MAX_VBDS * sizeof(vdisk_t), GFP_KERNEL);
+     if (!vbd_info)
+         return -ENOMEM;
+     nr_vbds  = xlvbd_get_vbd_info(vbd_info);
+     if ( nr_vbds < 0 )
+     {
+         kfree(vbd_info);
+         vbd_info = NULL;
+         nr_vbds  = 0;
+     }
+     else
+     {
+         for ( i = 0; i < nr_vbds; i++ )
+             xlvbd_init_device(&vbd_info[i]);
+     }
+     return 0;
+ }
index 0000000000000000000000000000000000000000,b17b430bf31a0ccaebe7d513fb43835453232238..3eb0701958535dabf7d1311fb7069f9b66f3bf11
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,20 +1,20 @@@
 -export-objs     := i386_ksyms.o skbuff.o ctrl_if.o
+ .S.o:
+       $(CC) $(AFLAGS) -traditional -c $< -o $*.o
+ all: kernel.o head.o init_task.o
+ O_TARGET := kernel.o
 -              reboot.o fixup.o skbuff.o
++export-objs     := i386_ksyms.o gnttab.o skbuff.o ctrl_if.o
+ obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o  \
+               ptrace.o ioport.o ldt.o setup.o time.o sys_i386.o \
+               i386_ksyms.o i387.o evtchn.o ctrl_if.o pci-dma.o \
++              reboot.o fixup.o gnttab.o skbuff.o
+ ifdef CONFIG_PCI
+ obj-y += pci-i386.o pci-pc.o
+ endif
+ include $(TOPDIR)/Rules.make
index 0000000000000000000000000000000000000000,d48bb7098db2710184144d947e7dba03bc60b77b..e8c563572bc11bec494e4ce1c9ed5ec8b98be4fb
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,39 +1,41 @@@
 -    .asciz "GUEST_OS=linux,GUEST_VER=2.4,XEN_VER=2.0,VIRT_BASE=0xC0000000"
+ .section __xen_guest
++    .ascii "GUEST_OS=linux,GUEST_VER=2.4,XEN_VER=3.0,VIRT_BASE=0xC0000000"
++    .ascii ",LOADER=generic"
++    .byte  0
+ .text
+ #include <linux/config.h>
+ #include <linux/threads.h>
+ #include <linux/linkage.h>
+ #include <asm/segment.h>
+ #include <asm/page.h>
+ #include <asm/pgtable.h>
+ #include <asm/desc.h>
+ ENTRY(stext)
+ ENTRY(_stext)
+         cld
+         lss stack_start,%esp
+         /* Copy the necessary stuff from xen_start_info structure. */
+         mov $SYMBOL_NAME(xen_start_info_union),%edi
+         mov $128,%ecx
+         rep movsl
+         jmp SYMBOL_NAME(start_kernel)
+ ENTRY(stack_start)
+       .long SYMBOL_NAME(init_task_union)+8192, __KERNEL_DS
+ .org 0x1000
+ ENTRY(empty_zero_page)
+ .org 0x2000
+ ENTRY(default_ldt)
+ .org 0x3000
+ ENTRY(cpu0_pte_quicklist)
+ .org 0x3400
+ ENTRY(cpu0_pgd_quicklist)
+         
+ .org 0x3800
index 0000000000000000000000000000000000000000,374c9b6c30b48212148911cd7e3c4b25f67849d8..6235778493b23ae5041a4a12f2d94d6416ee596f
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,271 +1,272 @@@
 -              flush_page_update_queue();
+ /*
+  * linux/kernel/ldt.c
+  *
+  * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds
+  * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
+  */
+ #include <linux/errno.h>
+ #include <linux/sched.h>
+ #include <linux/string.h>
+ #include <linux/mm.h>
+ #include <linux/smp.h>
+ #include <linux/smp_lock.h>
+ #include <linux/vmalloc.h>
+ #include <linux/slab.h>
++#include <asm/mmu_context.h>
+ #include <asm/uaccess.h>
+ #include <asm/system.h>
+ #include <asm/ldt.h>
+ #include <asm/desc.h>
+ #ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
+ static void flush_ldt(void *mm)
+ {
+       if (current->active_mm)
+               load_LDT(&current->active_mm->context);
+ }
+ #endif
+ static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
+ {
+       void *oldldt;
+       void *newldt;
+       int oldsize;
+       if (mincount <= pc->size)
+               return 0;
+       oldsize = pc->size;
+       mincount = (mincount+511)&(~511);
+       if (mincount*LDT_ENTRY_SIZE > PAGE_SIZE)
+               newldt = vmalloc(mincount*LDT_ENTRY_SIZE);
+       else
+               newldt = kmalloc(mincount*LDT_ENTRY_SIZE, GFP_KERNEL);
+       if (!newldt)
+               return -ENOMEM;
+       if (oldsize)
+               memcpy(newldt, pc->ldt, oldsize*LDT_ENTRY_SIZE);
+       oldldt = pc->ldt;
+       memset(newldt+oldsize*LDT_ENTRY_SIZE, 0, (mincount-oldsize)*LDT_ENTRY_SIZE);
+       wmb();
+       pc->ldt = newldt;
+       pc->size = mincount;
+       if (reload) {
+               make_pages_readonly(
+                       pc->ldt,
+                       (pc->size*LDT_ENTRY_SIZE)/PAGE_SIZE);
+               load_LDT(pc);
 -              flush_page_update_queue();
+ #ifdef CONFIG_SMP
+               if (current->mm->cpu_vm_mask != (1<<smp_processor_id()))
+                       smp_call_function(flush_ldt, 0, 1, 1);
+ #endif
+       }
+       wmb();
+       if (oldsize) {
++              make_pages_writable(
++                      oldldt, (oldsize*LDT_ENTRY_SIZE)/PAGE_SIZE);
+               if (oldsize*LDT_ENTRY_SIZE > PAGE_SIZE)
+                       vfree(oldldt);
+               else
+                       kfree(oldldt);
+       }
+       return 0;
+ }
+ static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
+ {
+       int err = alloc_ldt(new, old->size, 0);
+       if (err < 0) {
+               printk(KERN_WARNING "ldt allocation failed\n");
+               new->size = 0;
+               return err;
+       }
+       memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
+       make_pages_readonly(new->ldt, (new->size*LDT_ENTRY_SIZE)/PAGE_SIZE);
+       return 0;
+ }
+ /*
+  * we do not have to muck with descriptors here, that is
+  * done in switch_mm() as needed.
+  */
+ int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+ {
+       struct mm_struct * old_mm;
+       int retval = 0;
+       init_MUTEX(&mm->context.sem);
+       mm->context.size = 0;
+       old_mm = current->mm;
+       if (old_mm && old_mm->context.size > 0) {
+               down(&old_mm->context.sem);
+               retval = copy_ldt(&mm->context, &old_mm->context);
+               up(&old_mm->context.sem);
+       }
+       return retval;
+ }
+ /*
+  * No need to lock the MM as we are the last user
+  * Do not touch the ldt register, we are already
+  * in the next thread.
+  */
+ void destroy_context(struct mm_struct *mm)
+ {
+       if (mm->context.size) {
+               make_pages_writable(
+                       mm->context.ldt, 
+                       (mm->context.size*LDT_ENTRY_SIZE)/PAGE_SIZE);
+               if (mm->context.size*LDT_ENTRY_SIZE > PAGE_SIZE)
+                       vfree(mm->context.ldt);
+               else
+                       kfree(mm->context.ldt);
+               mm->context.size = 0;
+       }
+ }
+ static int read_ldt(void * ptr, unsigned long bytecount)
+ {
+       int err;
+       unsigned long size;
+       struct mm_struct * mm = current->mm;
+       if (!mm->context.size)
+               return 0;
+       if (bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES)
+               bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES;
+       down(&mm->context.sem);
+       size = mm->context.size*LDT_ENTRY_SIZE;
+       if (size > bytecount)
+               size = bytecount;
+       err = 0;
+       if (copy_to_user(ptr, mm->context.ldt, size))
+               err = -EFAULT;
+       up(&mm->context.sem);
+       if (err < 0)
+               return err;
+       if (size != bytecount) {
+               /* zero-fill the rest */
+               clear_user(ptr+size, bytecount-size);
+       }
+       return bytecount;
+ }
+ static int read_default_ldt(void * ptr, unsigned long bytecount)
+ {
+       int err;
+       unsigned long size;
+       void *address;
+       err = 0;
+       address = &default_ldt[0];
+       size = 5*sizeof(struct desc_struct);
+       if (size > bytecount)
+               size = bytecount;
+       err = size;
+       if (copy_to_user(ptr, address, size))
+               err = -EFAULT;
+       return err;
+ }
+ static int write_ldt(void * ptr, unsigned long bytecount, int oldmode)
+ {
+       struct mm_struct * mm = current->mm;
+       __u32 entry_1, entry_2, *lp;
+       unsigned long mach_lp;
+       int error;
+       struct modify_ldt_ldt_s ldt_info;
+       error = -EINVAL;
+       if (bytecount != sizeof(ldt_info))
+               goto out;
+       error = -EFAULT;        
+       if (copy_from_user(&ldt_info, ptr, sizeof(ldt_info)))
+               goto out;
+       error = -EINVAL;
+       if (ldt_info.entry_number >= LDT_ENTRIES)
+               goto out;
+       if (ldt_info.contents == 3) {
+               if (oldmode)
+                       goto out;
+               if (ldt_info.seg_not_present == 0)
+                       goto out;
+       }
+       down(&mm->context.sem);
+       if (ldt_info.entry_number >= mm->context.size) {
+               error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
+               if (error < 0)
+                       goto out_unlock;
+       }
+       lp = (__u32 *) ((ldt_info.entry_number << 3) + (char *) mm->context.ldt);
+       mach_lp = arbitrary_virt_to_machine(lp);
+       /* Allow LDTs to be cleared by the user. */
+       if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
+               if (oldmode ||
+                   (ldt_info.contents == 0             &&
+                    ldt_info.read_exec_only == 1       &&
+                    ldt_info.seg_32bit == 0            &&
+                    ldt_info.limit_in_pages == 0       &&
+                    ldt_info.seg_not_present == 1      &&
+                    ldt_info.useable == 0 )) {
+                       entry_1 = 0;
+                       entry_2 = 0;
+                       goto install;
+               }
+       }
+       entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
+                 (ldt_info.limit & 0x0ffff);
+       entry_2 = (ldt_info.base_addr & 0xff000000) |
+                 ((ldt_info.base_addr & 0x00ff0000) >> 16) |
+                 (ldt_info.limit & 0xf0000) |
+                 ((ldt_info.read_exec_only ^ 1) << 9) |
+                 (ldt_info.contents << 10) |
+                 ((ldt_info.seg_not_present ^ 1) << 15) |
+                 (ldt_info.seg_32bit << 22) |
+                 (ldt_info.limit_in_pages << 23) |
+                 0x7000;
+       if (!oldmode)
+               entry_2 |= (ldt_info.useable << 20);
+       /* Install the new entry ...  */
+ install:
+       error = HYPERVISOR_update_descriptor(mach_lp, entry_1, entry_2);
+ out_unlock:
+       up(&mm->context.sem);
+ out:
+       return error;
+ }
+ asmlinkage int sys_modify_ldt(int func, void *ptr, unsigned long bytecount)
+ {
+       int ret = -ENOSYS;
+       switch (func) {
+       case 0:
+               ret = read_ldt(ptr, bytecount);
+               break;
+       case 1:
+               ret = write_ldt(ptr, bytecount, 1);
+               break;
+       case 2:
+               ret = read_default_ldt(ptr, bytecount);
+               break;
+       case 0x11:
+               ret = write_ldt(ptr, bytecount, 0);
+               break;
+       }
+       return ret;
+ }
index 0000000000000000000000000000000000000000,ad7e82dc7904a796260149b13a7cc8bf25ef38d1..c9d553627f584a7cdb21d17ce8f12151f81bc833
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,460 +1,448 @@@
 -#include <asm/multicall.h>
 -#include <asm-xen/xen-public/dom0_ops.h>
+ /*
+  *  linux/arch/i386/kernel/process.c
+  *
+  *  Copyright (C) 1995  Linus Torvalds
+  *
+  *  Pentium III FXSR, SSE support
+  *    Gareth Hughes <gareth@valinux.com>, May 2000
+  */
+ /*
+  * This file handles the architecture-dependent parts of process handling..
+  */
+ #define __KERNEL_SYSCALLS__
+ #include <stdarg.h>
+ #include <linux/errno.h>
+ #include <linux/sched.h>
+ #include <linux/kernel.h>
+ #include <linux/mm.h>
+ #include <linux/smp.h>
+ #include <linux/smp_lock.h>
+ #include <linux/stddef.h>
+ #include <linux/unistd.h>
+ #include <linux/ptrace.h>
+ #include <linux/slab.h>
+ #include <linux/vmalloc.h>
+ #include <linux/user.h>
+ #include <linux/a.out.h>
+ #include <linux/interrupt.h>
+ #include <linux/config.h>
+ #include <linux/delay.h>
+ #include <linux/reboot.h>
+ #include <linux/init.h>
+ #include <linux/mc146818rtc.h>
+ #include <asm/uaccess.h>
+ #include <asm/pgtable.h>
+ #include <asm/system.h>
+ #include <asm/io.h>
+ #include <asm/ldt.h>
+ #include <asm/processor.h>
+ #include <asm/i387.h>
+ #include <asm/desc.h>
+ #include <asm/mmu_context.h>
 -    unsigned long eflags;
++#include <asm-xen/xen-public/physdev.h>
+ #include <linux/irq.h>
+ asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
+ int hlt_counter;
+ /*
+  * Powermanagement idle function, if any..
+  */
+ void (*pm_idle)(void);
+ /*
+  * Power off function, if any
+  */
+ void (*pm_power_off)(void);
+ void disable_hlt(void)
+ {
+     hlt_counter++;
+ }
+ void enable_hlt(void)
+ {
+     hlt_counter--;
+ }
+ /*
+  * The idle thread. There's no useful work to be
+  * done, so just try to conserve power and have a
+  * low exit latency (ie sit in a loop waiting for
+  * somebody to say that they'd like to reschedule)
+  */
+ void cpu_idle (void)
+ {
+     extern int set_timeout_timer(void);
+     /* Endless idle loop with no priority at all. */
+     init_idle();
+     current->nice = 20;
+     current->counter = -100;
+     for ( ; ; )
+     {
+         while ( !current->need_resched )
+         {
+             __cli();
+             if ( current->need_resched )
+             {
+                 /* The race-free check for events failed. */
+                 __sti();
+                 break;
+             }
+             else if ( set_timeout_timer() == 0 )
+             {
+                 /* NB. Blocking reenable events in a race-free manner. */
+                 HYPERVISOR_block();
+             }
+             else
+             {
+                 /* No race here: yielding will get us the CPU again anyway. */
+                 __sti();
+                 HYPERVISOR_yield();
+             }
+         }
+         schedule();
+         check_pgt_cache();
+     }
+ }
+ extern void show_trace(unsigned long* esp);
+ void show_regs(struct pt_regs * regs)
+ {
+     printk("\n");
+     printk("Pid: %d, comm: %20s\n", current->pid, current->comm);
+     printk("EIP: %04x:[<%08lx>] CPU: %d",0xffff & regs->xcs,regs->eip, smp_processor_id());
+     if (regs->xcs & 2)
+         printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
+     printk(" EFLAGS: %08lx    %s\n",regs->eflags, print_tainted());
+     printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
+            regs->eax,regs->ebx,regs->ecx,regs->edx);
+     printk("ESI: %08lx EDI: %08lx EBP: %08lx",
+            regs->esi, regs->edi, regs->ebp);
+     printk(" DS: %04x ES: %04x\n",
+            0xffff & regs->xds,0xffff & regs->xes);
+     show_trace(&regs->esp);
+ }
+ /*
+  * Create a kernel thread
+  */
+ int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+ {
+     long retval, d0;
+     __asm__ __volatile__(
+         "movl %%esp,%%esi\n\t"
+         "int $0x80\n\t"               /* Linux/i386 system call */
+         "cmpl %%esp,%%esi\n\t"        /* child or parent? */
+         "je 1f\n\t"           /* parent - jump */
+         /* Load the argument into eax, and push it.  That way, it does
+          * not matter whether the called function is compiled with
+          * -mregparm or not.  */
+         "movl %4,%%eax\n\t"
+         "pushl %%eax\n\t"             
+         "call *%5\n\t"                /* call fn */
+         "movl %3,%0\n\t"      /* exit */
+         "int $0x80\n"
+         "1:\t"
+         :"=&a" (retval), "=&S" (d0)
+         :"0" (__NR_clone), "i" (__NR_exit),
+         "r" (arg), "r" (fn),
+         "b" (flags | CLONE_VM)
+         : "memory");
+     return retval;
+ }
+ /*
+  * Free current thread data structures etc..
+  */
+ void exit_thread(void)
+ {
+     /* nothing to do ... */
+ }
+ void flush_thread(void)
+ {
+     struct task_struct *tsk = current;
+     memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
+     /*
+      * Forget coprocessor state..
+      */
+     clear_fpu(tsk);
+     tsk->used_math = 0;
+ }
+ void release_thread(struct task_struct *dead_task)
+ {
+     if (dead_task->mm) {
+         // temporary debugging check
+         if (dead_task->mm->context.size) {
+             printk("WARNING: dead process %8s still has LDT? <%p/%08x>\n",
+                    dead_task->comm, 
+                  dead_task->mm->context.ldt,
+                  dead_task->mm->context.size);
+             BUG();
+         }
+     }
+     //release_x86_irqs(dead_task);
+ }
+ /*
+  * Save a segment.
+  */
+ #define savesegment(seg,value) \
+       asm volatile("movl %%" #seg ",%0":"=m" (*(int *)&(value)))
+ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
+                 unsigned long unused,
+                 struct task_struct * p, struct pt_regs * regs)
+ {
+     struct pt_regs * childregs;
 -
 -    __asm__ __volatile__ ( "pushfl; popl %0" : "=r" (eflags) : );
 -    p->thread.io_pl = (eflags >> 12) & 3;
+     childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p)) - 1;
+     struct_cpy(childregs, regs);
+     childregs->eax = 0;
+     childregs->esp = esp;
+     p->thread.esp = (unsigned long) childregs;
+     p->thread.esp0 = (unsigned long) (childregs+1);
+     p->thread.eip = (unsigned long) ret_from_fork;
+     savesegment(fs,p->thread.fs);
+     savesegment(gs,p->thread.gs);
+     unlazy_fpu(current);
+     struct_cpy(&p->thread.i387, &current->thread.i387);
 -
 -    __cli();
 -
 -    /*
 -     * We clobber FS and GS here so that we avoid a GPF when restoring previous
 -     * task's FS/GS values in Xen when the LDT is switched. If we don't do this
 -     * then we can end up erroneously re-flushing the page-update queue when
 -     * we 'execute_multicall_list'.
 -     */
 -    __asm__ __volatile__ ( 
 -        "xorl %%eax,%%eax; movl %%eax,%%fs; movl %%eax,%%gs" : : : "eax" );
 -
 -    MULTICALL_flush_page_update_queue();
++    p->thread.io_pl = current->thread.io_pl;
+     return 0;
+ }
+ /*
+  * fill in the user structure for a core dump..
+  */
+ void dump_thread(struct pt_regs * regs, struct user * dump)
+ {
+     int i;
+ /* changed the size calculations - should hopefully work better. lbt */
+     dump->magic = CMAGIC;
+     dump->start_code = 0;
+     dump->start_stack = regs->esp & ~(PAGE_SIZE - 1);
+     dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
+     dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> PAGE_SHIFT;
+     dump->u_dsize -= dump->u_tsize;
+     dump->u_ssize = 0;
+     for (i = 0; i < 8; i++)
+         dump->u_debugreg[i] = current->thread.debugreg[i];  
+     if (dump->start_stack < TASK_SIZE)
+         dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
+     dump->regs.ebx = regs->ebx;
+     dump->regs.ecx = regs->ecx;
+     dump->regs.edx = regs->edx;
+     dump->regs.esi = regs->esi;
+     dump->regs.edi = regs->edi;
+     dump->regs.ebp = regs->ebp;
+     dump->regs.eax = regs->eax;
+     dump->regs.ds = regs->xds;
+     dump->regs.es = regs->xes;
+     savesegment(fs,dump->regs.fs);
+     savesegment(gs,dump->regs.gs);
+     dump->regs.orig_eax = regs->orig_eax;
+     dump->regs.eip = regs->eip;
+     dump->regs.cs = regs->xcs;
+     dump->regs.eflags = regs->eflags;
+     dump->regs.esp = regs->esp;
+     dump->regs.ss = regs->xss;
+     dump->u_fpvalid = dump_fpu (regs, &dump->i387);
+ }
+ /*
+  *    switch_to(x,yn) should switch tasks from x to y.
+  *
+  * We fsave/fwait so that an exception goes off at the right time
+  * (as a call from the fsave or fwait in effect) rather than to
+  * the wrong process. Lazy FP saving no longer makes any sense
+  * with modern CPU's, and this simplifies a lot of things (SMP
+  * and UP become the same).
+  *
+  * NOTE! We used to use the x86 hardware context switching. The
+  * reason for not using it any more becomes apparent when you
+  * try to recover gracefully from saved state that is no longer
+  * valid (stale segment register values in particular). With the
+  * hardware task-switch, there is no way to fix up bad state in
+  * a reasonable manner.
+  *
+  * The fact that Intel documents the hardware task-switching to
+  * be slow is a fairly red herring - this code is not noticeably
+  * faster. However, there _is_ some room for improvement here,
+  * so the performance issues may eventually be a valid point.
+  * More important, however, is the fact that this allows us much
+  * more flexibility.
+  */
+ void fastcall __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
+ {
+     struct thread_struct *next = &next_p->thread;
 -        queue_multicall0(__HYPERVISOR_fpu_taskswitch);
++    physdev_op_t op;
++    multicall_entry_t _mcl[8], *mcl = _mcl;
+     /*
+      * This is basically 'unlazy_fpu', except that we queue a multicall to 
+      * indicate FPU task switch, rather than synchronously trapping to Xen.
+      */
+     if ( prev_p->flags & PF_USEDFPU )
+     {
+       if ( cpu_has_fxsr )
+             asm volatile( "fxsave %0 ; fnclex"
+                           : "=m" (prev_p->thread.i387.fxsave) );
+       else
+             asm volatile( "fnsave %0 ; fwait"
+                           : "=m" (prev_p->thread.i387.fsave) );
+       prev_p->flags &= ~PF_USEDFPU;
 -    queue_multicall2(__HYPERVISOR_stack_switch, __KERNEL_DS, next->esp0);
 -    if ( xen_start_info.flags & SIF_PRIVILEGED ) 
++        mcl->op      = __HYPERVISOR_fpu_taskswitch;
++        mcl->args[0] = 1;
++        mcl++;
+     }
 -        dom0_op_t op;
 -        op.cmd           = DOM0_IOPL;
 -        op.u.iopl.domain = DOMID_SELF;
 -        op.u.iopl.iopl   = next->io_pl;
 -        op.interface_version = DOM0_INTERFACE_VERSION;
 -        queue_multicall1(__HYPERVISOR_dom0_op, (unsigned long)&op);
++    mcl->op      = __HYPERVISOR_stack_switch;
++    mcl->args[0] = __KERNEL_DS;
++    mcl->args[1] = next->esp0;
++    mcl++;
++
++    if ( prev_p->thread.io_pl != next->io_pl ) 
+     {
 -    /* EXECUTE ALL TASK SWITCH XEN SYSCALLS AT THIS POINT. */
 -    execute_multicall_list();
 -    __sti();
++        op.cmd             = PHYSDEVOP_SET_IOPL;
++      op.u.set_iopl.iopl = next->io_pl;
++        mcl->op      = __HYPERVISOR_physdev_op;
++        mcl->args[0] = (unsigned long)&op;
++        mcl++;
+     }
++    (void)HYPERVISOR_multicall(_mcl, mcl - _mcl);
+     /*
+      * Restore %fs and %gs.
+      */
+     loadsegment(fs, next->fs);
+     loadsegment(gs, next->gs);
+     /*
+      * Now maybe reload the debug registers
+      */
+     if ( next->debugreg[7] != 0 )
+     {
+         HYPERVISOR_set_debugreg(0, next->debugreg[0]);
+         HYPERVISOR_set_debugreg(1, next->debugreg[1]);
+         HYPERVISOR_set_debugreg(2, next->debugreg[2]);
+         HYPERVISOR_set_debugreg(3, next->debugreg[3]);
+         /* no 4 and 5 */
+         HYPERVISOR_set_debugreg(6, next->debugreg[6]);
+         HYPERVISOR_set_debugreg(7, next->debugreg[7]);
+     }
+ }
+ asmlinkage int sys_fork(struct pt_regs regs)
+ {
+     return do_fork(SIGCHLD, regs.esp, &regs, 0);
+ }
+ asmlinkage int sys_clone(struct pt_regs regs)
+ {
+     unsigned long clone_flags;
+     unsigned long newsp;
+     clone_flags = regs.ebx;
+     newsp = regs.ecx;
+     if (!newsp)
+         newsp = regs.esp;
+     return do_fork(clone_flags, newsp, &regs, 0);
+ }
+ /*
+  * This is trivial, and on the face of it looks like it
+  * could equally well be done in user mode.
+  *
+  * Not so, for quite unobvious reasons - register pressure.
+  * In user mode vfork() cannot have a stack frame, and if
+  * done by calling the "clone()" system call directly, you
+  * do not have enough call-clobbered registers to hold all
+  * the information you need.
+  */
+ asmlinkage int sys_vfork(struct pt_regs regs)
+ {
+     return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, &regs, 0);
+ }
+ /*
+  * sys_execve() executes a new program.
+  */
+ asmlinkage int sys_execve(struct pt_regs regs)
+ {
+     int error;
+     char * filename;
+     filename = getname((char *) regs.ebx);
+     error = PTR_ERR(filename);
+     if (IS_ERR(filename))
+         goto out;
+     error = do_execve(filename, (char **) regs.ecx, (char **) regs.edx, &regs);
+     if (error == 0)
+         current->ptrace &= ~PT_DTRACE;
+     putname(filename);
+  out:
+     return error;
+ }
+ /*
+  * These bracket the sleeping functions..
+  */
+ extern void scheduling_functions_start_here(void);
+ extern void scheduling_functions_end_here(void);
+ #define first_sched   ((unsigned long) scheduling_functions_start_here)
+ #define last_sched    ((unsigned long) scheduling_functions_end_here)
+ unsigned long get_wchan(struct task_struct *p)
+ {
+     unsigned long ebp, esp, eip;
+     unsigned long stack_page;
+     int count = 0;
+     if (!p || p == current || p->state == TASK_RUNNING)
+         return 0;
+     stack_page = (unsigned long)p;
+     esp = p->thread.esp;
+     if (!stack_page || esp < stack_page || esp > 8188+stack_page)
+         return 0;
+     /* include/asm-i386/system.h:switch_to() pushes ebp last. */
+     ebp = *(unsigned long *) esp;
+     do {
+         if (ebp < stack_page || ebp > 8184+stack_page)
+             return 0;
+         eip = *(unsigned long *) (ebp+4);
+         if (eip < first_sched || eip >= last_sched)
+             return eip;
+         ebp = *(unsigned long *) ebp;
+     } while (count++ < 16);
+     return 0;
+ }
+ #undef last_sched
+ #undef first_sched
index 0000000000000000000000000000000000000000,50fc7c1b133c83cc68d9cca15babbb2d6309b588..8fcbf0d7200fa33f3c899aa9462e7f6e6ab1e7f6
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,1222 +1,1213 @@@
 -#include <asm-xen/xen-public/dom0_ops.h>
+ /*
+  *  linux/arch/i386/kernel/setup.c
+  *
+  *  Copyright (C) 1995  Linus Torvalds
+  */
+ /*
+  * This file handles the architecture-dependent parts of initialization
+  */
+ #define __KERNEL_SYSCALLS__
+ static int errno;
+ #include <linux/errno.h>
+ #include <linux/sched.h>
+ #include <linux/kernel.h>
+ #include <linux/mm.h>
+ #include <linux/stddef.h>
+ #include <linux/unistd.h>
+ #include <linux/ptrace.h>
+ #include <linux/slab.h>
+ #include <linux/user.h>
+ #include <linux/a.out.h>
+ #include <linux/tty.h>
+ #include <linux/ioport.h>
+ #include <linux/delay.h>
+ #include <linux/config.h>
+ #include <linux/init.h>
+ #include <linux/apm_bios.h>
+ #ifdef CONFIG_BLK_DEV_RAM
+ #include <linux/blk.h>
+ #endif
+ #include <linux/highmem.h>
+ #include <linux/bootmem.h>
+ #include <linux/seq_file.h>
+ #include <linux/reboot.h>
+ #include <asm/processor.h>
+ #include <linux/console.h>
+ #include <linux/module.h>
+ #include <asm/mtrr.h>
+ #include <asm/uaccess.h>
+ #include <asm/system.h>
+ #include <asm/io.h>
+ #include <asm/smp.h>
+ #include <asm/msr.h>
+ #include <asm/desc.h>
+ #include <asm/dma.h>
+ #include <asm/mpspec.h>
+ #include <asm/mmu_context.h>
+ #include <asm/ctrl_if.h>
+ #include <asm/hypervisor.h>
 -unsigned long *phys_to_machine_mapping, *pfn_to_mfn_frame_list;
 -
 -multicall_entry_t multicall_list[8];
 -int nr_multicall_ents = 0;
++#include <asm-xen/xen-public/physdev.h>
+ #include <linux/netdevice.h>
+ #include <linux/rtnetlink.h>
+ #include <linux/tqueue.h>
+ #include <net/pkt_sched.h> /* dev_(de)activate */
+ /*
+  * Point at the empty zero page to start with. We map the real shared_info
+  * page as soon as fixmap is up and running.
+  */
+ shared_info_t *HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
 -    HYPERVISOR_vm_assist(VMASST_CMD_enable,
 -                         VMASST_TYPE_4gb_segments);
++unsigned int *phys_to_machine_mapping, *pfn_to_mfn_frame_list;
+ /*
+  * Machine setup..
+  */
+ char ignore_irq13;            /* set if exception 16 works */
+ struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
+ unsigned long mmu_cr4_features;
+ unsigned char * vgacon_mmap;
+ /*
+  * Bus types ..
+  */
+ #ifdef CONFIG_EISA
+ int EISA_bus;
+ #endif
+ int MCA_bus;
+ /* for MCA, but anyone else can use it if they want */
+ unsigned int machine_id;
+ unsigned int machine_submodel_id;
+ unsigned int BIOS_revision;
+ unsigned int mca_pentium_flag;
+ /* For PCI or other memory-mapped resources */
+ unsigned long pci_mem_start = 0x10000000;
+ /*
+  * Setup options
+  */
+ struct drive_info_struct { char dummy[32]; } drive_info;
+ struct screen_info screen_info;
+ struct apm_info apm_info;
+ struct sys_desc_table_struct {
+     unsigned short length;
+     unsigned char table[0];
+ };
+ unsigned char aux_device_present;
+ extern int root_mountflags;
+ extern char _text, _etext, _edata, _end;
+ extern int blk_nohighio;
+ int enable_acpi_smp_table;
+ /* Raw start-of-day parameters from the hypervisor. */
+ union xen_start_info_union xen_start_info_union;
+ #define COMMAND_LINE_SIZE 256
+ static char command_line[COMMAND_LINE_SIZE];
+ char saved_command_line[COMMAND_LINE_SIZE];
+ /* parse_mem_cmdline()
+  * returns the value of the mem= boot param converted to pages or 0
+  */ 
+ static int __init parse_mem_cmdline (char ** cmdline_p)
+ {
+     char c = ' ', *to = command_line, *from = saved_command_line;
+     int len = 0;
+     unsigned long long bytes;
+     int mem_param = 0;
+     /* Save unparsed command line copy for /proc/cmdline */
+     memcpy(saved_command_line, xen_start_info.cmd_line, COMMAND_LINE_SIZE);
+     saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
+     for (;;) {
+         /*
+          * "mem=nopentium" disables the 4MB page tables.
+          * "mem=XXX[kKmM]" defines a memory region from HIGH_MEM
+          * to <mem>, overriding the bios size.
+          * "mem=XXX[KkmM]@XXX[KkmM]" defines a memory region from
+          * <start> to <start>+<mem>, overriding the bios size.
+          */
+         if (c == ' ' && !memcmp(from, "mem=", 4)) {
+             if (to != command_line)
+                 to--;
+             if (!memcmp(from+4, "nopentium", 9)) {
+                 from += 9+4;
+             } else if (!memcmp(from+4, "exactmap", 8)) {
+                 from += 8+4;
+             } else {
+                 bytes = memparse(from+4, &from);
+                 mem_param = bytes>>PAGE_SHIFT;
+               if (*from == '@')
+                     (void)memparse(from+1, &from);
+             }
+         }
+         c = *(from++);
+         if (!c)
+             break;
+         if (COMMAND_LINE_SIZE <= ++len)
+             break;
+         *(to++) = c;
+     }
+     *to = '\0';
+     *cmdline_p = command_line;
+     return mem_param;
+ }
+ /*
+  * Every exception-fixup table is sorted (i.e., kernel main table, and every
+  * module table. Some elements may be out of order if they reference text.init,
+  * for example. 
+  */
+ static void sort_exception_table(struct exception_table_entry *start,
+                                  struct exception_table_entry *end)
+ {
+     struct exception_table_entry *p, *q, tmp;
+     for ( p = start; p < end; p++ )
+     {
+         for ( q = p-1; q > start; q-- )
+             if ( p->insn > q->insn )
+                 break;
+         if ( ++q != p )
+         {
+             tmp = *p;
+             memmove(q+1, q, (p-q)*sizeof(*p));
+             *q = tmp;
+         }
+     }
+ }
+ int xen_module_init(struct module *mod)
+ {
+     sort_exception_table(mod->ex_table_start, mod->ex_table_end);
+     return 0;
+ }
+ void __init setup_arch(char **cmdline_p)
+ {
+     int i,j;
+     unsigned long bootmap_size, start_pfn, lmax_low_pfn;
+     int mem_param;  /* user specified memory size in pages */
+     int boot_pfn;   /* low pages available for bootmem */
++    physdev_op_t op;
+     extern void hypervisor_callback(void);
+     extern void failsafe_callback(void);
+     extern unsigned long cpu0_pte_quicklist[];
+     extern unsigned long cpu0_pgd_quicklist[];
+     extern const struct exception_table_entry __start___ex_table[];
+     extern const struct exception_table_entry __stop___ex_table[];
+     extern char _stext;
+     /* Force a quick death if the kernel panics. */
+     extern int panic_timeout;
+     if ( panic_timeout == 0 )
+         panic_timeout = 1;
+     /* Ensure that the kernel exception-fixup table is sorted. */
+     sort_exception_table(__start___ex_table, __stop___ex_table);
+ #ifndef CONFIG_HIGHIO
+     blk_nohighio = 1;
+ #endif
 -    phys_to_machine_mapping = (unsigned long *)xen_start_info.mfn_list;
++    HYPERVISOR_vm_assist(
++        VMASST_CMD_enable, VMASST_TYPE_4gb_segments);
++    HYPERVISOR_vm_assist(
++        VMASST_CMD_enable, VMASST_TYPE_writable_pagetables);
+         
+     HYPERVISOR_set_callbacks(
+         __KERNEL_CS, (unsigned long)hypervisor_callback,
+         __KERNEL_CS, (unsigned long)failsafe_callback);
+     boot_cpu_data.pgd_quick = cpu0_pgd_quicklist;
+     boot_cpu_data.pte_quick = cpu0_pte_quicklist;
+     /* This must be initialized to UNNAMED_MAJOR for ipconfig to work
+        properly.  Setting ROOT_DEV to default to /dev/ram0 breaks initrd. */
+     ROOT_DEV = MKDEV(UNNAMED_MAJOR,0);
+     memset(&drive_info, 0, sizeof(drive_info));
+     memset(&screen_info, 0, sizeof(screen_info));
+     
+     /* This is drawn from a dump from vgacon:startup in standard Linux. */
+     screen_info.orig_video_mode = 3; 
+     screen_info.orig_video_isVGA = 1;
+     screen_info.orig_video_lines = 25;
+     screen_info.orig_video_cols = 80;
+     screen_info.orig_video_ega_bx = 3;
+     screen_info.orig_video_points = 16;
+     memset(&apm_info.bios, 0, sizeof(apm_info.bios));
+     aux_device_present = 0; 
+ #ifdef CONFIG_BLK_DEV_RAM
+     rd_image_start = 0;
+     rd_prompt = 0;
+     rd_doload = 0;
+ #endif
+     root_mountflags &= ~MS_RDONLY;
+     init_mm.start_code = (unsigned long) &_text;
+     init_mm.end_code = (unsigned long) &_etext;
+     init_mm.end_data = (unsigned long) &_edata;
+     init_mm.brk = (unsigned long) &_end;
+     /* The mem= kernel command line param overrides the detected amount
+      * of memory.   For xenolinux, if this override is larger than detected
+      * memory, then boot using only detected memory and make provisions to
+      * use all of the override value.   The hypervisor can give this
+      * domain more memory later on and it will be added to the free
+      * lists at that time.   See claim_new_pages() in
+      * arch/xen/drivers/balloon/balloon.c
+      */
+     mem_param = parse_mem_cmdline(cmdline_p);
+     if (mem_param < xen_start_info.nr_pages)
+         mem_param = xen_start_info.nr_pages;
+ #define PFN_UP(x)     (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
+ #define PFN_DOWN(x)   ((x) >> PAGE_SHIFT)
+ #define PFN_PHYS(x)   ((x) << PAGE_SHIFT)
+ /*
+  * 128MB for vmalloc(), iomap(), kmap(), and fixaddr mappings.
+  */
+ #define VMALLOC_RESERVE       (unsigned long)(128 << 20)
+ #define MAXMEM                (unsigned long)(HYPERVISOR_VIRT_START-PAGE_OFFSET-VMALLOC_RESERVE)
+ #define MAXMEM_PFN    PFN_DOWN(MAXMEM)
+ #define MAX_NONPAE_PFN        (1 << 20)
+     /*
+      * Determine low and high memory ranges:
+      */
+     lmax_low_pfn = max_pfn = mem_param;
+     if (lmax_low_pfn > MAXMEM_PFN) {
+         lmax_low_pfn = MAXMEM_PFN;
+ #ifndef CONFIG_HIGHMEM
+         /* Maximum memory usable is what is directly addressable */
+         printk(KERN_WARNING "Warning only %ldMB will be used.\n",
+                MAXMEM>>20);
+         if (max_pfn > MAX_NONPAE_PFN)
+             printk(KERN_WARNING "Use a PAE enabled kernel.\n");
+         else
+             printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n");
+         max_pfn = lmax_low_pfn;
+ #else /* !CONFIG_HIGHMEM */
+ #ifndef CONFIG_X86_PAE
+         if (max_pfn > MAX_NONPAE_PFN) {
+             max_pfn = MAX_NONPAE_PFN;
+             printk(KERN_WARNING "Warning only 4GB will be used.\n");
+             printk(KERN_WARNING "Use a PAE enabled kernel.\n");
+         }
+ #endif /* !CONFIG_X86_PAE */
+ #endif /* !CONFIG_HIGHMEM */
+     }
+ #ifdef CONFIG_HIGHMEM
+     highstart_pfn = highend_pfn = max_pfn;
+     if (max_pfn > MAXMEM_PFN) {
+         highstart_pfn = MAXMEM_PFN;
+         printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
+                pages_to_mb(highend_pfn - highstart_pfn));
+     }
+ #endif
 -    /* If we are a privileged guest OS then we should request IO privileges. */
 -    if ( xen_start_info.flags & SIF_PRIVILEGED ) 
 -    {
 -        dom0_op_t op;
 -        op.cmd           = DOM0_IOPL;
 -        op.u.iopl.domain = DOMID_SELF;
 -        op.u.iopl.iopl   = 1;
 -        if( HYPERVISOR_dom0_op(&op) != 0 )
 -            panic("Unable to obtain IOPL, despite being SIF_PRIVILEGED");
 -        current->thread.io_pl = 1;
 -    }
++    phys_to_machine_mapping = (unsigned int *)xen_start_info.mfn_list;
+     cur_pgd = init_mm.pgd = (pgd_t *)xen_start_info.pt_base;
+     start_pfn = (__pa(xen_start_info.pt_base) >> PAGE_SHIFT) + 
+         xen_start_info.nr_pt_frames;
+     /*
+      * Initialize the boot-time allocator, and free up all RAM. Then reserve 
+      * space for OS image, initrd, phys->machine table, bootstrap page table,
+      * and the bootmem bitmap. 
+      * NB. There is definitely enough room for the bootmem bitmap in the
+      * bootstrap page table. We are guaranteed to get >=512kB unused 'padding'
+      * for our own use after all bootstrap elements 
+      * (see asm-xen/xen-public/xen.h).
+      */
+     boot_pfn = min((int)xen_start_info.nr_pages,lmax_low_pfn);
+     bootmap_size = init_bootmem(start_pfn,boot_pfn);
+     free_bootmem(0, PFN_PHYS(boot_pfn));
+     reserve_bootmem(__pa(&_stext), 
+                     PFN_PHYS(start_pfn) + bootmap_size + PAGE_SIZE-1 - 
+                     __pa(&_stext));
+     /* init_bootmem() set the global max_low_pfn to boot_pfn.  Now max_low_pfn 
+      * can be set to the override value.
+      */
+     max_low_pfn = lmax_low_pfn;
+ #ifdef CONFIG_BLK_DEV_INITRD
+     if ( xen_start_info.mod_start != 0 )
+     {
+         if ( (__pa(xen_start_info.mod_start) + xen_start_info.mod_len) <= 
+              (max_low_pfn << PAGE_SHIFT) )
+         {
+             initrd_start = xen_start_info.mod_start;
+             initrd_end   = initrd_start + xen_start_info.mod_len;
+             initrd_below_start_ok = 1;
+         }
+         else
+         {
+             printk(KERN_ERR "initrd extends beyond end of memory "
+                    "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
+                    __pa(xen_start_info.mod_start) + xen_start_info.mod_len,
+                    max_low_pfn << PAGE_SHIFT);
+             initrd_start = 0;
+         }
+     }
+ #endif
+     paging_init();
+     /* Make sure we have a correctly sized P->M table. */
+     if ( max_pfn != xen_start_info.nr_pages )
+     {
+         phys_to_machine_mapping = alloc_bootmem_low_pages(
+             max_pfn * sizeof(unsigned long));
+         if ( max_pfn > xen_start_info.nr_pages )
+         {
+             memset(phys_to_machine_mapping, ~0,
+                    max_pfn * sizeof(unsigned long));
+             memcpy(phys_to_machine_mapping,
+                    (unsigned long *)xen_start_info.mfn_list,
+                    xen_start_info.nr_pages * sizeof(unsigned long));
+         }
+         else
+         {
+             memcpy(phys_to_machine_mapping,
+                    (unsigned long *)xen_start_info.mfn_list,
+                    max_pfn * sizeof(unsigned long));
+             if (HYPERVISOR_dom_mem_op(
+                 MEMOP_decrease_reservation,
+                 (unsigned long *)xen_start_info.mfn_list + max_pfn,
+                 xen_start_info.nr_pages - max_pfn, 0) !=
+                 (xen_start_info.nr_pages - max_pfn))
+                 BUG();
+         }
+         free_bootmem(__pa(xen_start_info.mfn_list), 
+                      PFN_PHYS(PFN_UP(xen_start_info.nr_pages *
+                                      sizeof(unsigned long))));
+     }
+     pfn_to_mfn_frame_list = alloc_bootmem_low_pages(PAGE_SIZE);
+     for ( i=0, j=0; i < max_pfn; i+=(PAGE_SIZE/sizeof(unsigned long)), j++ )
+     { 
+         pfn_to_mfn_frame_list[j] = 
+             virt_to_machine(&phys_to_machine_mapping[i]) >> PAGE_SHIFT;
+     }
+     HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list =
+       virt_to_machine(pfn_to_mfn_frame_list) >> PAGE_SHIFT;
 -    flush_page_update_queue();
++    op.cmd             = PHYSDEVOP_SET_IOPL;
++    op.u.set_iopl.iopl = current->thread.io_pl = 1;
++    HYPERVISOR_physdev_op(&op);
+     if (xen_start_info.flags & SIF_INITDOMAIN )
+     {
+         if( !(xen_start_info.flags & SIF_PRIVILEGED) )
+             panic("Xen granted us console access but not privileged status");
+ #if defined(CONFIG_VT)
+ #if defined(CONFIG_VGA_CONSOLE)
+         conswitchp = &vga_con;
+ #elif defined(CONFIG_DUMMY_CONSOLE)
+         conswitchp = &dummy_con;
+ #endif
+ #endif
+     }
+ }
+ static int cachesize_override __initdata = -1;
+ static int __init cachesize_setup(char *str)
+ {
+     get_option (&str, &cachesize_override);
+     return 1;
+ }
+ __setup("cachesize=", cachesize_setup);
+ static int __init highio_setup(char *str)
+ {
+     printk("i386: disabling HIGHMEM block I/O\n");
+     blk_nohighio = 1;
+     return 1;
+ }
+ __setup("nohighio", highio_setup);
+ static int __init get_model_name(struct cpuinfo_x86 *c)
+ {
+     unsigned int *v;
+     char *p, *q;
+     if (cpuid_eax(0x80000000) < 0x80000004)
+         return 0;
+     v = (unsigned int *) c->x86_model_id;
+     cpuid(0x80000002, &v[0], &v[1], &v[2], &v[3]);
+     cpuid(0x80000003, &v[4], &v[5], &v[6], &v[7]);
+     cpuid(0x80000004, &v[8], &v[9], &v[10], &v[11]);
+     c->x86_model_id[48] = 0;
+     /* Intel chips right-justify this string for some dumb reason;
+        undo that brain damage */
+     p = q = &c->x86_model_id[0];
+     while ( *p == ' ' )
+         p++;
+     if ( p != q ) {
+         while ( *p )
+             *q++ = *p++;
+         while ( q <= &c->x86_model_id[48] )
+             *q++ = '\0';      /* Zero-pad the rest */
+     }
+     return 1;
+ }
+ static void __init display_cacheinfo(struct cpuinfo_x86 *c)
+ {
+     unsigned int n, dummy, ecx, edx, l2size;
+     n = cpuid_eax(0x80000000);
+     if (n >= 0x80000005) {
+         cpuid(0x80000005, &dummy, &dummy, &ecx, &edx);
+         printk(KERN_INFO "CPU: L1 I Cache: %dK (%d bytes/line), D cache %dK (%d bytes/line)\n",
+                edx>>24, edx&0xFF, ecx>>24, ecx&0xFF);
+         c->x86_cache_size=(ecx>>24)+(edx>>24);        
+     }
+     if (n < 0x80000006)       /* Some chips just has a large L1. */
+         return;
+     ecx = cpuid_ecx(0x80000006);
+     l2size = ecx >> 16;
+     /* AMD errata T13 (order #21922) */
+     if ((c->x86_vendor == X86_VENDOR_AMD) && (c->x86 == 6)) {
+         if (c->x86_model == 3 && c->x86_mask == 0)    /* Duron Rev A0 */
+             l2size = 64;
+         if (c->x86_model == 4 &&
+             (c->x86_mask==0 || c->x86_mask==1))       /* Tbird rev A1/A2 */
+             l2size = 256;
+     }
+     /* Intel PIII Tualatin. This comes in two flavours.
+      * One has 256kb of cache, the other 512. We have no way
+      * to determine which, so we use a boottime override
+      * for the 512kb model, and assume 256 otherwise.
+      */
+     if ((c->x86_vendor == X86_VENDOR_INTEL) && (c->x86 == 6) &&
+         (c->x86_model == 11) && (l2size == 0))
+         l2size = 256;
+     if (c->x86_vendor == X86_VENDOR_CENTAUR) {
+       /* VIA C3 CPUs (670-68F) need further shifting. */
+       if ((c->x86 == 6) &&
+           ((c->x86_model == 7) || (c->x86_model == 8))) {
+               l2size >>= 8;
+       }
+       /* VIA also screwed up Nehemiah stepping 1, and made
+          it return '65KB' instead of '64KB'
+          - Note, it seems this may only be in engineering samples. */
+       if ((c->x86==6) && (c->x86_model==9) &&
+           (c->x86_mask==1) && (l2size==65))
+               l2size -= 1;
+     }
+     /* Allow user to override all this if necessary. */
+     if (cachesize_override != -1)
+         l2size = cachesize_override;
+     if ( l2size == 0 )
+         return;               /* Again, no L2 cache is possible */
+     c->x86_cache_size = l2size;
+     printk(KERN_INFO "CPU: L2 Cache: %dK (%d bytes/line)\n",
+            l2size, ecx & 0xFF);
+ }
+ static void __init init_c3(struct cpuinfo_x86 *c)
+ {
+     /* Test for Centaur Extended Feature Flags presence */
+     if (cpuid_eax(0xC0000000) >= 0xC0000001) {
+         /* store Centaur Extended Feature Flags as
+          * word 5 of the CPU capability bit array
+          */
+         c->x86_capability[5] = cpuid_edx(0xC0000001);
+     }
+    
+     switch (c->x86_model) {
+     case 9:   /* Nehemiah */
+     default:
+         get_model_name(c);
+         display_cacheinfo(c);
+         break;
+     }
+ }
+ static void __init init_centaur(struct cpuinfo_x86 *c)
+ {
+     /* Bit 31 in normal CPUID used for nonstandard 3DNow ID;
+        3DNow is IDd by bit 31 in extended CPUID (1*3231) anyway */
+     clear_bit(0*32+31, &c->x86_capability);
+   
+     switch (c->x86) {
+     case 6:
+         init_c3(c);
+         break;
+     default:
+         panic("Unsupported Centaur CPU (%i)\n", c->x86);
+     }
+ }
+ static int __init init_amd(struct cpuinfo_x86 *c)
+ {
+     int r;
+     /* Bit 31 in normal CPUID used for nonstandard 3DNow ID;
+        3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */
+     clear_bit(0*32+31, &c->x86_capability);
+       
+     r = get_model_name(c);
+     switch(c->x86)
+     {
+     case 5: /* We don't like AMD K6 */
+         panic("Unsupported AMD processor\n");
+     case 6:   /* An Athlon/Duron. We can trust the BIOS probably */
+         break;
+     }
+     display_cacheinfo(c);
+     return r;
+ }
+ static void __init init_intel(struct cpuinfo_x86 *c)
+ {
+     char *p = NULL;
+     unsigned int l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */
+     if (c->cpuid_level > 1) {
+         /* supports eax=2  call */
+         int i, j, n;
+         int regs[4];
+         unsigned char *dp = (unsigned char *)regs;
+         /* Number of times to iterate */
+         n = cpuid_eax(2) & 0xFF;
+         for ( i = 0 ; i < n ; i++ ) {
+             cpuid(2, &regs[0], &regs[1], &regs[2], &regs[3]);
+                       
+             /* If bit 31 is set, this is an unknown format */
+             for ( j = 0 ; j < 3 ; j++ ) {
+                 if ( regs[j] < 0 ) regs[j] = 0;
+             }
+             /* Byte 0 is level count, not a descriptor */
+             for ( j = 1 ; j < 16 ; j++ ) {
+                 unsigned char des = dp[j];
+                 unsigned char dl, dh;
+                 unsigned int cs;
+                 dh = des >> 4;
+                 dl = des & 0x0F;
+                               /* Black magic... */
+                 switch ( dh )
+                 {
+                 case 0:
+                     switch ( dl ) {
+                     case 6:
+                         /* L1 I cache */
+                         l1i += 8;
+                         break;
+                     case 8:
+                         /* L1 I cache */
+                         l1i += 16;
+                         break;
+                     case 10:
+                         /* L1 D cache */
+                         l1d += 8;
+                         break;
+                     case 12:
+                         /* L1 D cache */
+                         l1d += 16;
+                         break;
+                     default:;
+                         /* TLB, or unknown */
+                     }
+                     break;
+                 case 2:
+                     if ( dl ) {
+                         /* L3 cache */
+                         cs = (dl-1) << 9;
+                         l3 += cs;
+                     }
+                     break;
+                 case 4:
+                     if ( c->x86 > 6 && dl ) {
+                         /* P4 family */
+                         /* L3 cache */
+                         cs = 128 << (dl-1);
+                         l3 += cs;
+                         break;
+                     }
+                     /* else same as 8 - fall through */
+                 case 8:
+                     if ( dl ) {
+                         /* L2 cache */
+                         cs = 128 << (dl-1);
+                         l2 += cs;
+                     }
+                     break;
+                 case 6:
+                     if (dl > 5) {
+                         /* L1 D cache */
+                         cs = 8<<(dl-6);
+                         l1d += cs;
+                     }
+                     break;
+                 case 7:
+                     if ( dl >= 8 ) 
+                     {
+                         /* L2 cache */
+                         cs = 64<<(dl-8);
+                         l2 += cs;
+                     } else {
+                         /* L0 I cache, count as L1 */
+                         cs = dl ? (16 << (dl-1)) : 12;
+                         l1i += cs;
+                     }
+                     break;
+                 default:
+                     /* TLB, or something else we don't know about */
+                     break;
+                 }
+             }
+         }
+         if ( l1i || l1d )
+             printk(KERN_INFO "CPU: L1 I cache: %dK, L1 D cache: %dK\n",
+                    l1i, l1d);
+         if ( l2 )
+             printk(KERN_INFO "CPU: L2 cache: %dK\n", l2);
+         if ( l3 )
+             printk(KERN_INFO "CPU: L3 cache: %dK\n", l3);
+         /*
+          * This assumes the L3 cache is shared; it typically lives in
+          * the northbridge.  The L1 caches are included by the L2
+          * cache, and so should not be included for the purpose of
+          * SMP switching weights.
+          */
+         c->x86_cache_size = l2 ? l2 : (l1i+l1d);
+     }
+     /* SEP CPUID bug: Pentium Pro reports SEP but doesn't have it */
+     if ( c->x86 == 6 && c->x86_model < 3 && c->x86_mask < 3 )
+         clear_bit(X86_FEATURE_SEP, &c->x86_capability);
+       
+     /* Names for the Pentium II/Celeron processors 
+        detectable only by also checking the cache size.
+        Dixon is NOT a Celeron. */
+     if (c->x86 == 6) {
+         switch (c->x86_model) {
+         case 5:
+             if (l2 == 0)
+                 p = "Celeron (Covington)";
+             if (l2 == 256)
+                 p = "Mobile Pentium II (Dixon)";
+             break;
+                       
+         case 6:
+             if (l2 == 128)
+                 p = "Celeron (Mendocino)";
+             break;
+                       
+         case 8:
+             if (l2 == 128)
+                 p = "Celeron (Coppermine)";
+             break;
+         }
+     }
+     if ( p )
+         strcpy(c->x86_model_id, p);
+ }
+ void __init get_cpu_vendor(struct cpuinfo_x86 *c)
+ {
+     char *v = c->x86_vendor_id;
+     if (!strcmp(v, "GenuineIntel"))
+         c->x86_vendor = X86_VENDOR_INTEL;
+     else if (!strcmp(v, "AuthenticAMD"))
+         c->x86_vendor = X86_VENDOR_AMD;
+     else if (!strcmp(v, "CentaurHauls"))
+         c->x86_vendor = X86_VENDOR_CENTAUR;
+     else
+         c->x86_vendor = X86_VENDOR_UNKNOWN;
+ }
+ struct cpu_model_info {
+     int vendor;
+     int family;
+     char *model_names[16];
+ };
+ /* Naming convention should be: <Name> [(<Codename>)] */
+ /* This table only is used unless init_<vendor>() below doesn't set it; */
+ /* in particular, if CPUID levels 0x80000002..4 are supported, this isn't used */
+ static struct cpu_model_info cpu_models[] __initdata = {
+     { X86_VENDOR_INTEL,       6,
+       { "Pentium Pro A-step", "Pentium Pro", NULL, "Pentium II (Klamath)", 
+         NULL, "Pentium II (Deschutes)", "Mobile Pentium II",
+         "Pentium III (Katmai)", "Pentium III (Coppermine)", NULL,
+         "Pentium III (Cascades)", NULL, NULL, NULL, NULL }},
+     { X86_VENDOR_AMD, 6, /* Is this this really necessary?? */
+       { "Athlon", "Athlon",
+         "Athlon", NULL, "Athlon", NULL,
+         NULL, NULL, NULL,
+         NULL, NULL, NULL, NULL, NULL, NULL, NULL }}
+ };
+ /* Look up CPU names by table lookup. */
+ static char __init *table_lookup_model(struct cpuinfo_x86 *c)
+ {
+     struct cpu_model_info *info = cpu_models;
+     int i;
+     if ( c->x86_model >= 16 )
+         return NULL;  /* Range check */
+     for ( i = 0 ; i < sizeof(cpu_models)/sizeof(struct cpu_model_info) ; i++ ) {
+         if ( info->vendor == c->x86_vendor &&
+              info->family == c->x86 ) {
+             return info->model_names[c->x86_model];
+         }
+         info++;
+     }
+     return NULL;              /* Not found */
+ }
+ /* Standard macro to see if a specific flag is changeable */
+ static inline int flag_is_changeable_p(u32 flag)
+ {
+     u32 f1, f2;
+     asm("pushfl\n\t"
+         "pushfl\n\t"
+         "popl %0\n\t"
+         "movl %0,%1\n\t"
+         "xorl %2,%0\n\t"
+         "pushl %0\n\t"
+         "popfl\n\t"
+         "pushfl\n\t"
+         "popl %0\n\t"
+         "popfl\n\t"
+         : "=&r" (f1), "=&r" (f2)
+         : "ir" (flag));
+     return ((f1^f2) & flag) != 0;
+ }
+ /* Probe for the CPUID instruction */
+ static int __init have_cpuid_p(void)
+ {
+     return flag_is_changeable_p(X86_EFLAGS_ID);
+ }
+ #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
+ unsigned char eddnr;
+ struct edd_info edd[EDDMAXNR];
+ unsigned int edd_disk80_sig;
+ /**
+  * copy_edd() - Copy the BIOS EDD information
+  *              from empty_zero_page into a safe place.
+  *
+  */
+ static inline void copy_edd(void)
+ {
+      eddnr = EDD_NR;
+      memcpy(edd, EDD_BUF, sizeof(edd));
+      edd_disk80_sig = DISK80_SIGNATURE_BUFFER;
+ }
+ #else
+ static inline void copy_edd(void) {}
+ #endif
+ /*
+  * This does the hard work of actually picking apart the CPU stuff...
+  */
+ void __init identify_cpu(struct cpuinfo_x86 *c)
+ {
+     int junk, i;
+     u32 xlvl, tfms;
+     c->loops_per_jiffy = loops_per_jiffy;
+     c->x86_cache_size = -1;
+     c->x86_vendor = X86_VENDOR_UNKNOWN;
+     c->cpuid_level = -1;      /* CPUID not detected */
+     c->x86_model = c->x86_mask = 0;   /* So far unknown... */
+     c->x86_vendor_id[0] = '\0'; /* Unset */
+     c->x86_model_id[0] = '\0';  /* Unset */
+     memset(&c->x86_capability, 0, sizeof c->x86_capability);
+     c->hard_math = 1;
+     if ( !have_cpuid_p() ) {
+         panic("Processor must support CPUID\n");
+     } else {
+         /* CPU does have CPUID */
+         /* Get vendor name */
+         cpuid(0x00000000, &c->cpuid_level,
+               (int *)&c->x86_vendor_id[0],
+               (int *)&c->x86_vendor_id[8],
+               (int *)&c->x86_vendor_id[4]);
+               
+         get_cpu_vendor(c);
+         /* Initialize the standard set of capabilities */
+         /* Note that the vendor-specific code below might override */
+         /* Intel-defined flags: level 0x00000001 */
+         if ( c->cpuid_level >= 0x00000001 ) {
+                         u32 capability, excap;
+                         cpuid(0x00000001, &tfms, &junk, &excap, &capability);
+                         c->x86_capability[0] = capability;
+                         c->x86_capability[4] = excap;
+                         c->x86 = (tfms >> 8) & 15;
+                         c->x86_model = (tfms >> 4) & 15;
+                         if (c->x86 == 0xf) {
+                                 c->x86 += (tfms >> 20) & 0xff;
+                                 c->x86_model += ((tfms >> 16) & 0xF) << 4;
+                         }
+                         c->x86_mask = tfms & 15;
+         } else {
+             /* Have CPUID level 0 only - unheard of */
+             c->x86 = 4;
+         }
+         /* AMD-defined flags: level 0x80000001 */
+         xlvl = cpuid_eax(0x80000000);
+         if ( (xlvl & 0xffff0000) == 0x80000000 ) {
+             if ( xlvl >= 0x80000001 )
+                 c->x86_capability[1] = cpuid_edx(0x80000001);
+             if ( xlvl >= 0x80000004 )
+                 get_model_name(c); /* Default name */
+         }
+         /* Transmeta-defined flags: level 0x80860001 */
+         xlvl = cpuid_eax(0x80860000);
+         if ( (xlvl & 0xffff0000) == 0x80860000 ) {
+             if (  xlvl >= 0x80860001 )
+                 c->x86_capability[2] = cpuid_edx(0x80860001);
+         }
+     }
+     printk(KERN_DEBUG "CPU: Before vendor init, caps: %08x %08x %08x, vendor = %d\n",
+            c->x86_capability[0],
+            c->x86_capability[1],
+            c->x86_capability[2],
+            c->x86_vendor);
+     /*
+      * Vendor-specific initialization.  In this section we
+      * canonicalize the feature flags, meaning if there are
+      * features a certain CPU supports which CPUID doesn't
+      * tell us, CPUID claiming incorrect flags, or other bugs,
+      * we handle them here.
+      *
+      * At the end of this section, c->x86_capability better
+      * indicate the features this CPU genuinely supports!
+      */
+     switch ( c->x86_vendor ) {
+     case X86_VENDOR_AMD:
+         init_amd(c);
+         break;
+     case X86_VENDOR_INTEL:
+         init_intel(c);
+         break;
+     case X86_VENDOR_CENTAUR:
+         init_centaur(c);
+         break;
+         
+     default:
+         printk("Unsupported CPU vendor (%d) -- please report!\n",
+                c->x86_vendor);
+     }
+       
+     printk(KERN_DEBUG "CPU: After vendor init, caps: %08x %08x %08x %08x\n",
+            c->x86_capability[0],
+            c->x86_capability[1],
+            c->x86_capability[2],
+            c->x86_capability[3]);
+     /* If the model name is still unset, do table lookup. */
+     if ( !c->x86_model_id[0] ) {
+         char *p;
+         p = table_lookup_model(c);
+         if ( p )
+             strcpy(c->x86_model_id, p);
+         else
+             /* Last resort... */
+             sprintf(c->x86_model_id, "%02x/%02x",
+                     c->x86_vendor, c->x86_model);
+     }
+     /* Now the feature flags better reflect actual CPU features! */
+     printk(KERN_DEBUG "CPU:     After generic, caps: %08x %08x %08x %08x\n",
+            c->x86_capability[0],
+            c->x86_capability[1],
+            c->x86_capability[2],
+            c->x86_capability[3]);
+     /*
+      * On SMP, boot_cpu_data holds the common feature set between
+      * all CPUs; so make sure that we indicate which features are
+      * common between the CPUs.  The first time this routine gets
+      * executed, c == &boot_cpu_data.
+      */
+     if ( c != &boot_cpu_data ) {
+         /* AND the already accumulated flags with these */
+         for ( i = 0 ; i < NCAPINTS ; i++ )
+             boot_cpu_data.x86_capability[i] &= c->x86_capability[i];
+     }
+     printk(KERN_DEBUG "CPU:             Common caps: %08x %08x %08x %08x\n",
+            boot_cpu_data.x86_capability[0],
+            boot_cpu_data.x86_capability[1],
+            boot_cpu_data.x86_capability[2],
+            boot_cpu_data.x86_capability[3]);
+ }
+ /* These need to match <asm/processor.h> */
+ static char *cpu_vendor_names[] __initdata = {
+     "Intel", "Cyrix", "AMD", "UMC", "NexGen", "Centaur", "Rise", "Transmeta" };
+ void __init print_cpu_info(struct cpuinfo_x86 *c)
+ {
+     char *vendor = NULL;
+     if (c->x86_vendor < sizeof(cpu_vendor_names)/sizeof(char *))
+         vendor = cpu_vendor_names[c->x86_vendor];
+     else if (c->cpuid_level >= 0)
+         vendor = c->x86_vendor_id;
+     if (vendor && strncmp(c->x86_model_id, vendor, strlen(vendor)))
+         printk("%s ", vendor);
+     if (!c->x86_model_id[0])
+         printk("%d86", c->x86);
+     else
+         printk("%s", c->x86_model_id);
+     if (c->x86_mask || c->cpuid_level >= 0) 
+         printk(" stepping %02x\n", c->x86_mask);
+     else
+         printk("\n");
+ }
+ /*
+  *    Get CPU information for use by the procfs.
+  */
+ static int show_cpuinfo(struct seq_file *m, void *v)
+ {
+     /* 
+      * These flag bits must match the definitions in <asm/cpufeature.h>.
+      * NULL means this bit is undefined or reserved; either way it doesn't
+      * have meaning as far as Linux is concerned.  Note that it's important
+      * to realize there is a difference between this table and CPUID -- if
+      * applications want to get the raw CPUID data, they should access
+      * /dev/cpu/<cpu_nr>/cpuid instead.
+        */
+     static char *x86_cap_flags[] = {
+         /* Intel-defined */
+         "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
+         "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
+         "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx",
+         "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe",
+         /* AMD-defined */
+         NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+         NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL,
+         NULL, NULL, NULL, "mp", NULL, NULL, "mmxext", NULL,
+         NULL, NULL, NULL, NULL, NULL, "lm", "3dnowext", "3dnow",
+         /* Transmeta-defined */
+         "recovery", "longrun", NULL, "lrti", NULL, NULL, NULL, NULL,
+         NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+         NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+         NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+         /* Other (Linux-defined) */
+         "cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr", 
+       NULL, NULL, NULL, NULL,
+         NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+         NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+         NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+         /* Intel-defined (#2) */
+         "pni", NULL, NULL, "monitor", "ds_cpl", NULL, NULL, "tm2",
+         "est", NULL, "cid", NULL, NULL, NULL, NULL, NULL,
+         NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+         NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+         /* VIA/Cyrix/Centaur-defined */
+         NULL, NULL, "xstore", NULL, NULL, NULL, NULL, NULL,
+         NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+         NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+         NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+     };
+     struct cpuinfo_x86 *c = v;
+     int i, n = c - cpu_data;
+     int fpu_exception;
+ #ifdef CONFIG_SMP
+     if (!(cpu_online_map & (1<<n)))
+         return 0;
+ #endif
+     seq_printf(m, "processor\t: %d\n"
+                "vendor_id\t: %s\n"
+                "cpu family\t: %d\n"
+                "model\t\t: %d\n"
+                "model name\t: %s\n",
+                n,
+                c->x86_vendor_id[0] ? c->x86_vendor_id : "unknown",
+                c->x86,
+                c->x86_model,
+                c->x86_model_id[0] ? c->x86_model_id : "unknown");
+     if (c->x86_mask || c->cpuid_level >= 0)
+         seq_printf(m, "stepping\t: %d\n", c->x86_mask);
+     else
+         seq_printf(m, "stepping\t: unknown\n");
+     if ( test_bit(X86_FEATURE_TSC, &c->x86_capability) ) {
+         seq_printf(m, "cpu MHz\t\t: %lu.%03lu\n",
+                    cpu_khz / 1000, (cpu_khz % 1000));
+     }
+     /* Cache size */
+     if (c->x86_cache_size >= 0)
+         seq_printf(m, "cache size\t: %d KB\n", c->x86_cache_size);
+       
+       /* We use exception 16 if we have hardware math and we've either seen it or the CPU claims it is internal */
+     fpu_exception = c->hard_math && (ignore_irq13 || cpu_has_fpu);
+     seq_printf(m, "fdiv_bug\t: %s\n"
+                "hlt_bug\t\t: %s\n"
+                "f00f_bug\t: %s\n"
+                "coma_bug\t: %s\n"
+                "fpu\t\t: %s\n"
+                "fpu_exception\t: %s\n"
+                "cpuid level\t: %d\n"
+                "wp\t\t: %s\n"
+                "flags\t\t:",
+                c->fdiv_bug ? "yes" : "no",
+                c->hlt_works_ok ? "no" : "yes",
+                c->f00f_bug ? "yes" : "no",
+                c->coma_bug ? "yes" : "no",
+                c->hard_math ? "yes" : "no",
+                fpu_exception ? "yes" : "no",
+                c->cpuid_level,
+                c->wp_works_ok ? "yes" : "no");
+     for ( i = 0 ; i < 32*NCAPINTS ; i++ )
+         if ( test_bit(i, &c->x86_capability) &&
+              x86_cap_flags[i] != NULL )
+             seq_printf(m, " %s", x86_cap_flags[i]);
+     seq_printf(m, "\nbogomips\t: %lu.%02lu\n\n",
+                c->loops_per_jiffy/(500000/HZ),
+                (c->loops_per_jiffy/(5000/HZ)) % 100);
+     return 0;
+ }
+ static void *c_start(struct seq_file *m, loff_t *pos)
+ {
+     return *pos < NR_CPUS ? cpu_data + *pos : NULL;
+ }
+ static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+ {
+     ++*pos;
+     return c_start(m, pos);
+ }
+ static void c_stop(struct seq_file *m, void *v)
+ {
+ }
+ struct seq_operations cpuinfo_op = {
+     start:    c_start,
+     next:     c_next,
+     stop:     c_stop,
+     show:     show_cpuinfo,
+ };
+ unsigned long cpu_initialized __initdata = 0;
+ /*
+  * cpu_init() initializes state that is per-CPU. Some data is already
+  * initialized (naturally) in the bootstrap process, such as the GDT
+  * and IDT. We reload them nevertheless, this function acts as a
+  * 'CPU state barrier', nothing should get across.
+  */
+ void __init cpu_init (void)
+ {
+     int nr = smp_processor_id();
+     if (test_and_set_bit(nr, &cpu_initialized)) {
+         printk(KERN_WARNING "CPU#%d already initialized!\n", nr);
+         for (;;) __sti();
+     }
+     printk(KERN_INFO "Initializing CPU#%d\n", nr);
+     /*
+      * set up and load the per-CPU TSS and LDT
+      */
+     atomic_inc(&init_mm.mm_count);
+     current->active_mm = &init_mm;
+     if(current->mm)
+         BUG();
+     enter_lazy_tlb(&init_mm, current, nr);
+     HYPERVISOR_stack_switch(__KERNEL_DS, current->thread.esp0);
+     load_LDT(&init_mm.context);
+     /* Force FPU initialization. */
+     current->flags &= ~PF_USEDFPU;
+     current->used_math = 0;
+     stts();
+ }
index 0000000000000000000000000000000000000000,ada06dd973f6bbd512e2cc0eb4818857f4d2cdda..b87fc3804c4f0ced2d3ea2d8d5438f21e25173ca
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,628 +1,619 @@@
 -                  mmu_update_t u;
 -                  u.ptr  = MMU_EXTENDED_COMMAND;
 -                  u.ptr |= (unsigned long)&default_ldt[0];
 -                  u.val  = MMUEXT_SET_LDT | (5 << MMUEXT_CMD_SHIFT);
 -                  if ( unlikely(HYPERVISOR_mmu_update(&u, 1, NULL) < 0) )
 -                  {
 -                      show_trace(NULL);
 -                      panic("Failed to install default LDT");
 -                  }
+ /*
+  *  linux/arch/i386/traps.c
+  *
+  *  Copyright (C) 1991, 1992  Linus Torvalds
+  *
+  *  Pentium III FXSR, SSE support
+  *    Gareth Hughes <gareth@valinux.com>, May 2000
+  */
+ /*
+  * 'Traps.c' handles hardware traps and faults after we have saved some
+  * state in 'asm.s'.
+  */
+ #include <linux/config.h>
+ #include <linux/sched.h>
+ #include <linux/kernel.h>
+ #include <linux/string.h>
+ #include <linux/errno.h>
+ #include <linux/ptrace.h>
+ #include <linux/timer.h>
+ #include <linux/mm.h>
+ #include <linux/init.h>
+ #include <linux/delay.h>
+ #include <linux/spinlock.h>
+ #include <linux/interrupt.h>
+ #include <linux/highmem.h>
+ #include <asm/system.h>
+ #include <asm/uaccess.h>
+ #include <asm/io.h>
+ #include <asm/atomic.h>
+ #include <asm/debugreg.h>
+ #include <asm/desc.h>
+ #include <asm/i387.h>
+ #include <asm/smp.h>
+ #include <asm/pgalloc.h>
+ #include <asm/hypervisor.h>
+ #include <linux/irq.h>
+ #include <linux/module.h>
+ asmlinkage int system_call(void);
+ asmlinkage void lcall7(void);
+ asmlinkage void lcall27(void);
+ asmlinkage void divide_error(void);
+ asmlinkage void debug(void);
+ asmlinkage void int3(void);
+ asmlinkage void overflow(void);
+ asmlinkage void bounds(void);
+ asmlinkage void invalid_op(void);
+ asmlinkage void device_not_available(void);
+ asmlinkage void double_fault(void);
+ asmlinkage void coprocessor_segment_overrun(void);
+ asmlinkage void invalid_TSS(void);
+ asmlinkage void segment_not_present(void);
+ asmlinkage void stack_segment(void);
+ asmlinkage void general_protection(void);
+ asmlinkage void page_fault(void);
+ asmlinkage void coprocessor_error(void);
+ asmlinkage void simd_coprocessor_error(void);
+ asmlinkage void alignment_check(void);
+ asmlinkage void fixup_4gb_segment(void);
+ asmlinkage void machine_check(void);
+ int kstack_depth_to_print = 24;
+ /*
+  * If the address is either in the .text section of the
+  * kernel, or in the vmalloc'ed module regions, it *may* 
+  * be the address of a calling routine
+  */
+ #ifdef CONFIG_MODULES
+ extern struct module *module_list;
+ extern struct module kernel_module;
+ static inline int kernel_text_address(unsigned long addr)
+ {
+       int retval = 0;
+       struct module *mod;
+       if (addr >= (unsigned long) &_stext &&
+           addr <= (unsigned long) &_etext)
+               return 1;
+       for (mod = module_list; mod != &kernel_module; mod = mod->next) {
+               /* mod_bound tests for addr being inside the vmalloc'ed
+                * module area. Of course it'd be better to test only
+                * for the .text subset... */
+               if (mod_bound(addr, 0, mod)) {
+                       retval = 1;
+                       break;
+               }
+       }
+       return retval;
+ }
+ #else
+ static inline int kernel_text_address(unsigned long addr)
+ {
+       return (addr >= (unsigned long) &_stext &&
+               addr <= (unsigned long) &_etext);
+ }
+ #endif
+ void show_trace(unsigned long * stack)
+ {
+       int i;
+       unsigned long addr;
+       if (!stack)
+               stack = (unsigned long*)&stack;
+       printk("Call Trace: ");
+       i = 1;
+       while (((long) stack & (THREAD_SIZE-1)) != 0) {
+               addr = *stack++;
+               if (kernel_text_address(addr)) {
+                       if (i && ((i % 6) == 0))
+                               printk("\n   ");
+                       printk("[<%08lx>] ", addr);
+                       i++;
+               }
+       }
+       printk("\n");
+ }
+ void show_trace_task(struct task_struct *tsk)
+ {
+       unsigned long esp = tsk->thread.esp;
+       /* User space on another CPU? */
+       if ((esp ^ (unsigned long)tsk) & (PAGE_MASK<<1))
+               return;
+       show_trace((unsigned long *)esp);
+ }
+ void show_stack(unsigned long * esp)
+ {
+       unsigned long *stack;
+       int i;
+       // debugging aid: "show_stack(NULL);" prints the
+       // back trace for this cpu.
+       if(esp==NULL)
+               esp=(unsigned long*)&esp;
+       stack = esp;
+       for(i=0; i < kstack_depth_to_print; i++) {
+               if (((long) stack & (THREAD_SIZE-1)) == 0)
+                       break;
+               if (i && ((i % 8) == 0))
+                       printk("\n       ");
+               printk("%08lx ", *stack++);
+       }
+       printk("\n");
+       show_trace(esp);
+ }
+ void show_registers(struct pt_regs *regs)
+ {
+       int in_kernel = 1;
+       unsigned long esp;
+       unsigned short ss;
+       esp = (unsigned long) (&regs->esp);
+       ss = __KERNEL_DS;
+       if (regs->xcs & 2) {
+               in_kernel = 0;
+               esp = regs->esp;
+               ss = regs->xss & 0xffff;
+       }
+       printk(KERN_ALERT "CPU:    %d\n", smp_processor_id() );
+       printk(KERN_ALERT "EIP:    %04x:[<%08lx>]    %s\n",
+              0xffff & regs->xcs, regs->eip, print_tainted());
+       printk(KERN_ALERT "EFLAGS: %08lx\n",regs->eflags);
+       printk(KERN_ALERT "eax: %08lx   ebx: %08lx   ecx: %08lx   edx: %08lx\n",
+               regs->eax, regs->ebx, regs->ecx, regs->edx);
+       printk(KERN_ALERT "esi: %08lx   edi: %08lx   ebp: %08lx   esp: %08lx\n",
+               regs->esi, regs->edi, regs->ebp, esp);
+       printk(KERN_ALERT "ds: %04x   es: %04x   ss: %04x\n",
+               regs->xds & 0xffff, regs->xes & 0xffff, ss);
+       printk(KERN_ALERT "Process %s (pid: %d, stackpage=%08lx)",
+               current->comm, current->pid, 4096+(unsigned long)current);
+       /*
+        * When in-kernel, we also print out the stack and code at the
+        * time of the fault..
+        */
+       if (in_kernel) {
+               printk(KERN_ALERT "\nStack: ");
+               show_stack((unsigned long*)esp);
+ #if 0
+                 {
+                         int i;
+                       printk(KERN_ALERT "\nCode: ");
+                       if(regs->eip < PAGE_OFFSET)
+                               goto bad;
+                       for(i=0;i<20;i++)
+                       {
+                               unsigned char c;
+                               if(__get_user(c, &((unsigned char*)regs->eip)[i])) {
+ bad:
+                                       printk(KERN_ALERT " Bad EIP value.");
+                                       break;
+                               }
+                               printk("%02x ", c);
+                       }
+               }
+ #endif
+       }
+       printk(KERN_ALERT "\n");
+ }     
+ spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
+ void die(const char * str, struct pt_regs * regs, long err)
+ {
+       console_verbose();
+       spin_lock_irq(&die_lock);
+       bust_spinlocks(1);
+       printk("%s: %04lx\n", str, err & 0xffff);
+       show_registers(regs);
+       bust_spinlocks(0);
+       spin_unlock_irq(&die_lock);
+       do_exit(SIGSEGV);
+ }
+ static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
+ {
+       if (!(2 & regs->xcs))
+               die(str, regs, err);
+ }
+ static void inline do_trap(int trapnr, int signr, char *str,
+                          struct pt_regs * regs, long error_code,
+                            siginfo_t *info)
+ {
+       if (!(regs->xcs & 2))
+               goto kernel_trap;
+       /*trap_signal:*/ {
+               struct task_struct *tsk = current;
+               tsk->thread.error_code = error_code;
+               tsk->thread.trap_no = trapnr;
+               if (info)
+                       force_sig_info(signr, info, tsk);
+               else
+                       force_sig(signr, tsk);
+               return;
+       }
+       kernel_trap: {
+               unsigned long fixup = search_exception_table(regs->eip);
+               if (fixup)
+                       regs->eip = fixup;
+               else    
+                       die(str, regs, error_code);
+               return;
+       }
+ }
+ #define DO_ERROR(trapnr, signr, str, name) \
+ asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
+ { \
+       do_trap(trapnr, signr, str, regs, error_code, NULL); \
+ }
+ #define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
+ asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
+ { \
+       siginfo_t info; \
+       info.si_signo = signr; \
+       info.si_errno = 0; \
+       info.si_code = sicode; \
+       info.si_addr = (void *)siaddr; \
+       do_trap(trapnr, signr, str, regs, error_code, &info); \
+ }
+ DO_ERROR_INFO( 0, SIGFPE,  "divide error", divide_error, FPE_INTDIV, regs->eip)
+ DO_ERROR( 3, SIGTRAP, "int3", int3)
+ DO_ERROR( 4, SIGSEGV, "overflow", overflow)
+ DO_ERROR( 5, SIGSEGV, "bounds", bounds)
+ DO_ERROR_INFO( 6, SIGILL,  "invalid operand", invalid_op, ILL_ILLOPN, regs->eip)
+ DO_ERROR( 7, SIGSEGV, "device not available", device_not_available)
+ DO_ERROR( 8, SIGSEGV, "double fault", double_fault)
+ DO_ERROR( 9, SIGFPE,  "coprocessor segment overrun", coprocessor_segment_overrun)
+ DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
+ DO_ERROR(11, SIGBUS,  "segment not present", segment_not_present)
+ DO_ERROR(12, SIGBUS,  "stack segment", stack_segment)
+ DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0)
+ DO_ERROR(18, SIGBUS, "machine check", machine_check)
+ asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
+ {
+       /*
+        * If we trapped on an LDT access then ensure that the default_ldt is
+        * loaded, if nothing else. We load default_ldt lazily because LDT
+        * switching costs time and many applications don't need it.
+        */
+       if ( unlikely((error_code & 6) == 4) )
+       {
+               unsigned long ldt;
+               __asm__ __volatile__ ( "sldt %0" : "=r" (ldt) );
+               if ( ldt == 0 )
+               {
 -    HYPERVISOR_set_fast_trap(SYSCALL_VECTOR);
++                    xen_set_ldt((unsigned long)&default_ldt[0], 5);
+                   return;
+               }
+       }
+       if (!(regs->xcs & 2))
+               goto gp_in_kernel;
+       current->thread.error_code = error_code;
+       current->thread.trap_no = 13;
+       force_sig(SIGSEGV, current);
+       return;
+ gp_in_kernel:
+       {
+               unsigned long fixup;
+               fixup = search_exception_table(regs->eip);
+               if (fixup) {
+                       regs->eip = fixup;
+                       return;
+               }
+               die("general protection fault", regs, error_code);
+       }
+ }
+ asmlinkage void do_debug(struct pt_regs * regs, long error_code)
+ {
+     unsigned int condition;
+     struct task_struct *tsk = current;
+     siginfo_t info;
+     condition = HYPERVISOR_get_debugreg(6);
+     /* Mask out spurious debug traps due to lazy DR7 setting */
+     if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
+         if (!tsk->thread.debugreg[7])
+             goto clear_dr7;
+     }
+     /* Save debug status register where ptrace can see it */
+     tsk->thread.debugreg[6] = condition;
+     /* Mask out spurious TF errors due to lazy TF clearing */
+     if (condition & DR_STEP) {
+         /*
+          * The TF error should be masked out only if the current
+          * process is not traced and if the TRAP flag has been set
+          * previously by a tracing process (condition detected by
+          * the PT_DTRACE flag); remember that the i386 TRAP flag
+          * can be modified by the process itself in user mode,
+          * allowing programs to debug themselves without the ptrace()
+          * interface.
+          */
+         if ((tsk->ptrace & (PT_DTRACE|PT_PTRACED)) == PT_DTRACE)
+             goto clear_TF;
+     }
+     /* Ok, finally something we can handle */
+     tsk->thread.trap_no = 1;
+     tsk->thread.error_code = error_code;
+     info.si_signo = SIGTRAP;
+     info.si_errno = 0;
+     info.si_code = TRAP_BRKPT;
+         
+     /* If this is a kernel mode trap, save the user PC on entry to 
+      * the kernel, that's what the debugger can make sense of.
+      */
+     info.si_addr = ((regs->xcs & 2) == 0) ? (void *)tsk->thread.eip : 
+                                             (void *)regs->eip;
+     force_sig_info(SIGTRAP, &info, tsk);
+     /* Disable additional traps. They'll be re-enabled when
+      * the signal is delivered.
+      */
+  clear_dr7:
+     HYPERVISOR_set_debugreg(7, 0);
+     return;
+  clear_TF:
+     regs->eflags &= ~TF_MASK;
+     return;
+ }
+ /*
+  * Note that we play around with the 'TS' bit in an attempt to get
+  * the correct behaviour even in the presence of the asynchronous
+  * IRQ13 behaviour
+  */
+ void math_error(void *eip)
+ {
+       struct task_struct * task;
+       siginfo_t info;
+       unsigned short cwd, swd;
+       /*
+        * Save the info for the exception handler and clear the error.
+        */
+       task = current;
+       save_init_fpu(task);
+       task->thread.trap_no = 16;
+       task->thread.error_code = 0;
+       info.si_signo = SIGFPE;
+       info.si_errno = 0;
+       info.si_code = __SI_FAULT;
+       info.si_addr = eip;
+       /*
+        * (~cwd & swd) will mask out exceptions that are not set to unmasked
+        * status.  0x3f is the exception bits in these regs, 0x200 is the
+        * C1 reg you need in case of a stack fault, 0x040 is the stack
+        * fault bit.  We should only be taking one exception at a time,
+        * so if this combination doesn't produce any single exception,
+        * then we have a bad program that isn't syncronizing its FPU usage
+        * and it will suffer the consequences since we won't be able to
+        * fully reproduce the context of the exception
+        */
+       cwd = get_fpu_cwd(task);
+       swd = get_fpu_swd(task);
+       switch (((~cwd) & swd & 0x3f) | (swd & 0x240)) {
+               case 0x000:
+               default:
+                       break;
+               case 0x001: /* Invalid Op */
+               case 0x041: /* Stack Fault */
+               case 0x241: /* Stack Fault | Direction */
+                       info.si_code = FPE_FLTINV;
+                       break;
+               case 0x002: /* Denormalize */
+               case 0x010: /* Underflow */
+                       info.si_code = FPE_FLTUND;
+                       break;
+               case 0x004: /* Zero Divide */
+                       info.si_code = FPE_FLTDIV;
+                       break;
+               case 0x008: /* Overflow */
+                       info.si_code = FPE_FLTOVF;
+                       break;
+               case 0x020: /* Precision */
+                       info.si_code = FPE_FLTRES;
+                       break;
+       }
+       force_sig_info(SIGFPE, &info, task);
+ }
+ asmlinkage void do_coprocessor_error(struct pt_regs * regs, long error_code)
+ {
+       ignore_irq13 = 1;
+       math_error((void *)regs->eip);
+ }
+ void simd_math_error(void *eip)
+ {
+       struct task_struct * task;
+       siginfo_t info;
+       unsigned short mxcsr;
+       /*
+        * Save the info for the exception handler and clear the error.
+        */
+       task = current;
+       save_init_fpu(task);
+       task->thread.trap_no = 19;
+       task->thread.error_code = 0;
+       info.si_signo = SIGFPE;
+       info.si_errno = 0;
+       info.si_code = __SI_FAULT;
+       info.si_addr = eip;
+       /*
+        * The SIMD FPU exceptions are handled a little differently, as there
+        * is only a single status/control register.  Thus, to determine which
+        * unmasked exception was caught we must mask the exception mask bits
+        * at 0x1f80, and then use these to mask the exception bits at 0x3f.
+        */
+       mxcsr = get_fpu_mxcsr(task);
+       switch (~((mxcsr & 0x1f80) >> 7) & (mxcsr & 0x3f)) {
+               case 0x000:
+               default:
+                       break;
+               case 0x001: /* Invalid Op */
+                       info.si_code = FPE_FLTINV;
+                       break;
+               case 0x002: /* Denormalize */
+               case 0x010: /* Underflow */
+                       info.si_code = FPE_FLTUND;
+                       break;
+               case 0x004: /* Zero Divide */
+                       info.si_code = FPE_FLTDIV;
+                       break;
+               case 0x008: /* Overflow */
+                       info.si_code = FPE_FLTOVF;
+                       break;
+               case 0x020: /* Precision */
+                       info.si_code = FPE_FLTRES;
+                       break;
+       }
+       force_sig_info(SIGFPE, &info, task);
+ }
+ asmlinkage void do_simd_coprocessor_error(struct pt_regs * regs,
+                                         long error_code)
+ {
+       if (cpu_has_xmm) {
+               /* Handle SIMD FPU exceptions on PIII+ processors. */
+               ignore_irq13 = 1;
+               simd_math_error((void *)regs->eip);
+       } else {
+               die_if_kernel("cache flush denied", regs, error_code);
+               current->thread.trap_no = 19;
+               current->thread.error_code = error_code;
+               force_sig(SIGSEGV, current);
+       }
+ }
+ /*
+  *  'math_state_restore()' saves the current math information in the
+  * old math state array, and gets the new ones from the current task
+  *
+  * Careful.. There are problems with IBM-designed IRQ13 behaviour.
+  * Don't touch unless you *really* know how it works.
+  */
+ asmlinkage void math_state_restore(struct pt_regs regs)
+ {
+       /*
+        * A trap in kernel mode can be ignored. It'll be the fast XOR or
+        * copying libraries, which will correctly save/restore state and
+        * reset the TS bit in CR0.
+        */
+       if ( (regs.xcs & 2) == 0 )
+               return;
+       if (current->used_math) {
+               restore_fpu(current);
+       } else {
+               init_fpu();
+       }
+       current->flags |= PF_USEDFPU;   /* So we fnsave on switch_to() */
+ }
+ #define _set_gate(gate_addr,type,dpl,addr) \
+ do { \
+   int __d0, __d1; \
+   __asm__ __volatile__ ("movw %%dx,%%ax\n\t" \
+       "movw %4,%%dx\n\t" \
+       "movl %%eax,%0\n\t" \
+       "movl %%edx,%1" \
+       :"=m" (*((long *) (gate_addr))), \
+        "=m" (*(1+(long *) (gate_addr))), "=&a" (__d0), "=&d" (__d1) \
+       :"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \
+        "3" ((char *) (addr)),"2" (__KERNEL_CS << 16)); \
+ } while (0)
+ static void __init set_call_gate(void *a, void *addr)
+ {
+       _set_gate(a,12,3,addr);
+ }
+ /* NB. All these are "trap gates" (i.e. events_mask isn't cleared). */
+ static trap_info_t trap_table[] = {
+     {  0, 0, __KERNEL_CS, (unsigned long)divide_error                },
+     {  1, 0, __KERNEL_CS, (unsigned long)debug                       },
+     {  3, 3, __KERNEL_CS, (unsigned long)int3                        },
+     {  4, 3, __KERNEL_CS, (unsigned long)overflow                    },
+     {  5, 3, __KERNEL_CS, (unsigned long)bounds                      },
+     {  6, 0, __KERNEL_CS, (unsigned long)invalid_op                  },
+     {  7, 0, __KERNEL_CS, (unsigned long)device_not_available        },
+     {  8, 0, __KERNEL_CS, (unsigned long)double_fault                },
+     {  9, 0, __KERNEL_CS, (unsigned long)coprocessor_segment_overrun },
+     { 10, 0, __KERNEL_CS, (unsigned long)invalid_TSS                 },
+     { 11, 0, __KERNEL_CS, (unsigned long)segment_not_present         },
+     { 12, 0, __KERNEL_CS, (unsigned long)stack_segment               },
+     { 13, 0, __KERNEL_CS, (unsigned long)general_protection          },
+     { 14, 0, __KERNEL_CS, (unsigned long)page_fault                  },
+     { 15, 0, __KERNEL_CS, (unsigned long)fixup_4gb_segment           },
+     { 16, 0, __KERNEL_CS, (unsigned long)coprocessor_error           },
+     { 17, 0, __KERNEL_CS, (unsigned long)alignment_check             },
+     { 18, 0, __KERNEL_CS, (unsigned long)machine_check               },
+     { 19, 0, __KERNEL_CS, (unsigned long)simd_coprocessor_error      },
+     { SYSCALL_VECTOR, 
+           3, __KERNEL_CS, (unsigned long)system_call                 },
+     {  0, 0,           0, 0                           }
+ };
+ void __init trap_init(void)
+ {
+     HYPERVISOR_set_trap_table(trap_table);    
+     /*
+      * The default LDT is a single-entry callgate to lcall7 for iBCS and a
+      * callgate to lcall27 for Solaris/x86 binaries.
+      */
+     clear_page(&default_ldt[0]);
+     set_call_gate(&default_ldt[0],lcall7);
+     set_call_gate(&default_ldt[4],lcall27);
+     __make_page_readonly(&default_ldt[0]);
+     cpu_init();
+ }
index 0000000000000000000000000000000000000000,76d95ff03a718f505447d2295e5cd0ed03940865..7db6463e0924444a0563fde38a8844d47003f106
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,306 +1,302 @@@
 -      if ( flush_page_update_queue() != 0 )
 -              return;
 -
+ /*
+  *  linux/arch/i386/mm/fault.c
+  *
+  *  Copyright (C) 1995  Linus Torvalds
+  */
+ #include <linux/signal.h>
+ #include <linux/sched.h>
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+ #include <linux/string.h>
+ #include <linux/types.h>
+ #include <linux/ptrace.h>
+ #include <linux/mman.h>
+ #include <linux/mm.h>
+ #include <linux/smp.h>
+ #include <linux/smp_lock.h>
+ #include <linux/interrupt.h>
+ #include <linux/init.h>
+ #include <linux/tty.h>
+ #include <linux/vt_kern.h>            /* For unblank_screen() */
+ #include <asm/system.h>
+ #include <asm/uaccess.h>
+ #include <asm/pgalloc.h>
+ #include <asm/hardirq.h>
+ extern void die(const char *,struct pt_regs *,long);
+ pgd_t *cur_pgd;
+ extern spinlock_t timerlist_lock;
+ /*
+  * Unlock any spinlocks which will prevent us from getting the
+  * message out (timerlist_lock is acquired through the
+  * console unblank code)
+  */
+ void bust_spinlocks(int yes)
+ {
+       spin_lock_init(&timerlist_lock);
+       if (yes) {
+               oops_in_progress = 1;
+       } else {
+               int loglevel_save = console_loglevel;
+ #ifdef CONFIG_VT
+               unblank_screen();
+ #endif
+               oops_in_progress = 0;
+               /*
+                * OK, the message is on the console.  Now we call printk()
+                * without oops_in_progress set so that printk will give klogd
+                * a poke.  Hold onto your hats...
+                */
+               console_loglevel = 15;          /* NMI oopser may have shut the console up */
+               printk(" ");
+               console_loglevel = loglevel_save;
+       }
+ }
+ /*
+  * This routine handles page faults.  It determines the address,
+  * and the problem, and then passes it off to one of the appropriate
+  * routines.
+  *
+  * error_code:
+  *    bit 0 == 0 means no page found, 1 means protection fault
+  *    bit 1 == 0 means read, 1 means write
+  *    bit 2 == 0 means kernel, 1 means user-mode
+  */
+ asmlinkage void do_page_fault(struct pt_regs *regs, 
+                               unsigned long error_code,
+                               unsigned long address)
+ {
+       struct task_struct *tsk = current;
+       struct mm_struct *mm;
+       struct vm_area_struct * vma;
+       unsigned long page;
+       unsigned long fixup;
+       int write;
+       siginfo_t info;
+         /* Set the "privileged fault" bit to something sane. */
+         error_code &= 3;
+         error_code |= (regs->xcs & 2) << 1;
 -                XEN_flush_page_update_queue(); /* flush PMD update */
+       /*
+        * We fault-in kernel-space virtual memory on-demand. The
+        * 'reference' page table is init_mm.pgd.
+        *
+        * NOTE! We MUST NOT take any locks for this case. We may
+        * be in an interrupt or a critical region, and should
+        * only copy the information from the master page table,
+        * nothing more.
+        *
+        * This verifies that the fault happens in kernel space
+        * (error_code & 4) == 0, and that the fault was not a
+        * protection error (error_code & 1) == 0.
+        */
+       if (address >= TASK_SIZE && !(error_code & 5))
+               goto vmalloc_fault;
+       mm = tsk->mm;
+       info.si_code = SEGV_MAPERR;
+       /*
+        * If we're in an interrupt or have no user
+        * context, we must not take the fault..
+        */
+       if (in_interrupt() || !mm)
+               goto no_context;
+       down_read(&mm->mmap_sem);
+       vma = find_vma(mm, address);
+       if (!vma)
+               goto bad_area;
+       if (vma->vm_start <= address)
+               goto good_area;
+       if (!(vma->vm_flags & VM_GROWSDOWN))
+               goto bad_area;
+       if (error_code & 4) {
+               /*
+                * accessing the stack below %esp is always a bug.
+                * The "+ 32" is there due to some instructions (like
+                * pusha) doing post-decrement on the stack and that
+                * doesn't show up until later..
+                */
+               if (address + 32 < regs->esp)
+                       goto bad_area;
+       }
+       if (expand_stack(vma, address))
+               goto bad_area;
+ /*
+  * Ok, we have a good vm_area for this memory access, so
+  * we can handle it..
+  */
+ good_area:
+       info.si_code = SEGV_ACCERR;
+       write = 0;
+       switch (error_code & 3) {
+               default:        /* 3: write, present */
+                       /* fall through */
+               case 2:         /* write, not present */
+                       if (!(vma->vm_flags & VM_WRITE))
+                               goto bad_area;
+                       write++;
+                       break;
+               case 1:         /* read, present */
+                       goto bad_area;
+               case 0:         /* read, not present */
+                       if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+                               goto bad_area;
+       }
+  survive:
+       /*
+        * If for any reason at all we couldn't handle the fault,
+        * make sure we exit gracefully rather than endlessly redo
+        * the fault.
+        */
+       switch (handle_mm_fault(mm, vma, address, write)) {
+       case 1:
+               tsk->min_flt++;
+               break;
+       case 2:
+               tsk->maj_flt++;
+               break;
+       case 0:
+               goto do_sigbus;
+       default:
+               goto out_of_memory;
+       }
+       up_read(&mm->mmap_sem);
+       return;
+ /*
+  * Something tried to access memory that isn't in our memory map..
+  * Fix it, but check if it's kernel or user first..
+  */
+ bad_area:
+       up_read(&mm->mmap_sem);
+       /* User mode accesses just cause a SIGSEGV */
+       if (error_code & 4) {
+               tsk->thread.cr2 = address;
+               /* Kernel addresses are always protection faults */
+               tsk->thread.error_code = error_code | (address >= TASK_SIZE);
+               tsk->thread.trap_no = 14;
+               info.si_signo = SIGSEGV;
+               info.si_errno = 0;
+               /* info.si_code has been set above */
+               info.si_addr = (void *)address;
+               force_sig_info(SIGSEGV, &info, tsk);
+               return;
+       }
+ no_context:
+       /* Are we prepared to handle this kernel fault?  */
+       if ((fixup = search_exception_table(regs->eip)) != 0) {
+               regs->eip = fixup;
+               return;
+       }
+ /*
+  * Oops. The kernel tried to access some bad page. We'll have to
+  * terminate things with extreme prejudice.
+  */
+       bust_spinlocks(1);
+       if (address < PAGE_SIZE)
+               printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
+       else
+               printk(KERN_ALERT "Unable to handle kernel paging request");
+       printk(" at virtual address %08lx\n",address);
+       printk(" printing eip:\n");
+       printk("%08lx\n", regs->eip);
+         page = ((unsigned long *) cur_pgd)[address >> 22];
+         printk(KERN_ALERT "*pde=%08lx(%08lx)\n", page, machine_to_phys(page));
+       if (page & 1) {
+               page &= PAGE_MASK;
+               address &= 0x003ff000;
+                 page = machine_to_phys(page);
+               page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT];
+                 printk(KERN_ALERT "*pte=%08lx(%08lx)\n", page, 
+                        machine_to_phys(page));
+       }
+       die("Oops", regs, error_code);
+       bust_spinlocks(0);
+       do_exit(SIGKILL);
+ /*
+  * We ran out of memory, or some other thing happened to us that made
+  * us unable to handle the page fault gracefully.
+  */
+ out_of_memory:
+       if (tsk->pid == 1) {
+               yield();
+               goto survive;
+       }
+       up_read(&mm->mmap_sem);
+       printk("VM: killing process %s\n", tsk->comm);
+       if (error_code & 4)
+               do_exit(SIGKILL);
+       goto no_context;
+ do_sigbus:
+       up_read(&mm->mmap_sem);
+       /*
+        * Send a sigbus, regardless of whether we were in kernel
+        * or user mode.
+        */
+       tsk->thread.cr2 = address;
+       tsk->thread.error_code = error_code;
+       tsk->thread.trap_no = 14;
+       info.si_signo = SIGBUS;
+       info.si_errno = 0;
+       info.si_code = BUS_ADRERR;
+       info.si_addr = (void *)address;
+       force_sig_info(SIGBUS, &info, tsk);
+       /* Kernel mode? Handle exceptions or die */
+       if (!(error_code & 4))
+               goto no_context;
+       return;
+ vmalloc_fault:
+       {
+               /*
+                * Synchronize this task's top level page-table
+                * with the 'reference' page table.
+                *
+                * Do _not_ use "tsk" here. We might be inside
+                * an interrupt in the middle of a task switch..
+                */
+               int offset = __pgd_offset(address);
+               pgd_t *pgd, *pgd_k;
+               pmd_t *pmd, *pmd_k;
+               pte_t *pte_k;
+               pgd = offset + cur_pgd;
+               pgd_k = init_mm.pgd + offset;
+               if (!pgd_present(*pgd_k))
+                       goto no_context;
+               set_pgd(pgd, *pgd_k);
+               
+               pmd = pmd_offset(pgd, address);
+               pmd_k = pmd_offset(pgd_k, address);
+               if (!pmd_present(*pmd_k))
+                       goto no_context;
+               set_pmd(pmd, *pmd_k);
+               pte_k = pte_offset(pmd_k, address);
+               if (!pte_present(*pte_k))
+                       goto no_context;
+               return;
+       }
+ }
index 0000000000000000000000000000000000000000,40a5af9273b9ab027abf3dc37c7369712907461d..88d775bcd409e039b5e5be41499bd7e5664a37dc
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,487 +1,482 @@@
 -    queue_l1_entry_update(pte, phys | pgprot_val(prot));
+ /*
+  *  linux/arch/i386/mm/init.c
+  *
+  *  Copyright (C) 1995  Linus Torvalds
+  *
+  *  Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
+  */
+ #include <linux/config.h>
+ #include <linux/signal.h>
+ #include <linux/sched.h>
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+ #include <linux/string.h>
+ #include <linux/types.h>
+ #include <linux/ptrace.h>
+ #include <linux/mman.h>
+ #include <linux/mm.h>
+ #include <linux/swap.h>
+ #include <linux/smp.h>
+ #include <linux/init.h>
+ #ifdef CONFIG_BLK_DEV_INITRD
+ #include <linux/blk.h>
+ #endif
+ #include <linux/highmem.h>
+ #include <linux/pagemap.h>
+ #include <linux/bootmem.h>
+ #include <linux/slab.h>
+ #include <asm/processor.h>
+ #include <asm/system.h>
+ #include <asm/uaccess.h>
+ #include <asm/pgtable.h>
+ #include <asm/pgalloc.h>
+ #include <asm/dma.h>
+ #include <asm/apic.h>
+ #include <asm/tlb.h>
+ /* XEN: We *cannot* use mmx_clear_page() this early. Force dumb memset(). */
+ #undef clear_page
+ #define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
+ mmu_gather_t mmu_gathers[NR_CPUS];
+ unsigned long highstart_pfn, highend_pfn;
+ static unsigned long totalram_pages;
+ static unsigned long totalhigh_pages;
+ int do_check_pgt_cache(int low, int high)
+ {
+     int freed = 0;
+     if(pgtable_cache_size > high) {
+         do {
+             if (!QUICKLIST_EMPTY(pgd_quicklist)) {
+                 free_pgd_slow(get_pgd_fast());
+                 freed++;
+             }
+             if (!QUICKLIST_EMPTY(pte_quicklist)) {
+                 pte_free_slow(pte_alloc_one_fast(NULL, 0));
+                 freed++;
+             }
+         } while(pgtable_cache_size > low);
+     }
+     return freed;
+ }
+  
+ /*
+  * NOTE: pagetable_init alloc all the fixmap pagetables contiguous on the
+  * physical space so we can cache the place of the first one and move
+  * around without checking the pgd every time.
+  */
+ #if CONFIG_HIGHMEM
+ pte_t *kmap_pte;
+ pgprot_t kmap_prot;
+ #define kmap_get_fixmap_pte(vaddr) \
+     pte_offset(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
+ void __init kmap_init(void)
+ {
+     unsigned long kmap_vstart;
+     /* cache the first kmap pte */
+     kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
+     kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
+     kmap_prot = PAGE_KERNEL;
+ }
+ #endif /* CONFIG_HIGHMEM */
+ void show_mem(void)
+ {
+     int i, total = 0, reserved = 0;
+     int shared = 0, cached = 0;
+     int highmem = 0;
+     printk("Mem-info:\n");
+     show_free_areas();
+     printk("Free swap:       %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
+     i = max_mapnr;
+     while (i-- > 0) {
+         total++;
+         if (PageHighMem(mem_map+i))
+             highmem++;
+         if (PageReserved(mem_map+i))
+             reserved++;
+         else if (PageSwapCache(mem_map+i))
+             cached++;
+         else if (page_count(mem_map+i))
+             shared += page_count(mem_map+i) - 1;
+     }
+     printk("%d pages of RAM\n", total);
+     printk("%d pages of HIGHMEM\n",highmem);
+     printk("%d reserved pages\n",reserved);
+     printk("%d pages shared\n",shared);
+     printk("%d pages swap cached\n",cached);
+     printk("%ld pages in page table cache\n",pgtable_cache_size);
+     show_buffers();
+ }
+ /* References to section boundaries */
+ extern char _text, _etext, _edata, __bss_start, _end;
+ extern char __init_begin, __init_end;
+ static inline void set_pte_phys (unsigned long vaddr,
+                                  unsigned long phys, pgprot_t prot)
+ {
+     pgd_t *pgd;
+     pmd_t *pmd;
+     pte_t *pte;
+     pgd = init_mm.pgd + __pgd_offset(vaddr);
+     if (pgd_none(*pgd)) {
+         printk("PAE BUG #00!\n");
+         return;
+     }
+     pmd = pmd_offset(pgd, vaddr);
+     if (pmd_none(*pmd)) {
+         printk("PAE BUG #01!\n");
+         return;
+     }
+     pte = pte_offset(pmd, vaddr);
 -                queue_l1_entry_update(kpte,
 -                                      (*(unsigned long *)kpte)&~_PAGE_RW);
 -
++    set_pte(pte, (pte_t) { phys | pgprot_val(prot) });
+     /*
+      * It's enough to flush this one mapping.
+      * (PGE mappings get flushed as well)
+      */
+     __flush_tlb_one(vaddr);
+ }
+ void __set_fixmap(enum fixed_addresses idx, unsigned long phys, 
+                   pgprot_t flags)
+ {
+     unsigned long address = __fix_to_virt(idx);
+     if (idx >= __end_of_fixed_addresses) {
+         printk("Invalid __set_fixmap\n");
+         return;
+     }
+     set_pte_phys(address, phys, flags);
+ }
+ void clear_fixmap(enum fixed_addresses idx)
+ {
+     set_pte_phys(__fix_to_virt(idx), 0, __pgprot(0));
+ }
+ static void __init fixrange_init (unsigned long start, 
+                                   unsigned long end, pgd_t *pgd_base)
+ {
+     pgd_t *pgd, *kpgd;
+     pmd_t *pmd, *kpmd;
+     pte_t *pte, *kpte;
+     int i, j;
+     unsigned long vaddr;
+     vaddr = start;
+     i = __pgd_offset(vaddr);
+     j = __pmd_offset(vaddr);
+     pgd = pgd_base + i;
+     for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) {
+ #if CONFIG_X86_PAE
+         if (pgd_none(*pgd)) {
+             pmd = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+             set_pgd(pgd, __pgd(__pa(pmd) + 0x1));
+             if (pmd != pmd_offset(pgd, 0))
+                 printk("PAE BUG #02!\n");
+         }
+         pmd = pmd_offset(pgd, vaddr);
+ #else
+         pmd = (pmd_t *)pgd;
+ #endif
+         for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
+             if (pmd_none(*pmd)) {
+                 pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+                 clear_page(pte);
+                 kpgd = pgd_offset_k((unsigned long)pte);
+                 kpmd = pmd_offset(kpgd, (unsigned long)pte);
+                 kpte = pte_offset(kpmd, (unsigned long)pte);
 -      
 -    XEN_flush_page_update_queue();
++                set_pte(kpte, pte_wrprotect(*kpte));
+                 set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)));
+             }
+             vaddr += PMD_SIZE;
+         }
+         j = 0;
+     }
 -            queue_l1_entry_update(kpte,
 -                                  (*(unsigned long *)kpte)&~_PAGE_RW);
+ }
+ static void __init pagetable_init (void)
+ {
+     unsigned long vaddr, end, ram_end;
+     pgd_t *kpgd, *pgd, *pgd_base;
+     int i, j, k;
+     pmd_t *kpmd, *pmd;
+     pte_t *kpte, *pte, *pte_base;
+     ram_end = end = (unsigned long)__va(max_low_pfn * PAGE_SIZE);
+     if ( xen_start_info.nr_pages < max_low_pfn )
+         ram_end = (unsigned long)__va(xen_start_info.nr_pages * PAGE_SIZE);
+     pgd_base = init_mm.pgd;
+     i = __pgd_offset(PAGE_OFFSET);
+     pgd = pgd_base + i;
+     for (; i < PTRS_PER_PGD; pgd++, i++) {
+         vaddr = i*PGDIR_SIZE;
+         if (vaddr >= end)
+             break;
+         pmd = (pmd_t *)pgd;
+         for (j = 0; j < PTRS_PER_PMD; pmd++, j++) {
+             vaddr = i*PGDIR_SIZE + j*PMD_SIZE;
+             if (vaddr >= end)
+                 break;
+             /* Filled in for us already? */
+             if ( pmd_val(*pmd) & _PAGE_PRESENT )
+                 continue;
+             pte_base = pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+             clear_page(pte_base);
+             for (k = 0; k < PTRS_PER_PTE; pte++, k++) {
+                 vaddr = i*PGDIR_SIZE + j*PMD_SIZE + k*PAGE_SIZE;
+                 if (vaddr >= ram_end)
+                     break;
+                 *pte = mk_pte_phys(__pa(vaddr), PAGE_KERNEL);
+             }
+             kpgd = pgd_offset_k((unsigned long)pte_base);
+             kpmd = pmd_offset(kpgd, (unsigned long)pte_base);
+             kpte = pte_offset(kpmd, (unsigned long)pte_base);
 -            XEN_flush_page_update_queue();
++            set_pte(kpte, pte_wrprotect(*kpte));
+             set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte_base)));
+         }
+     }
+     /*
+      * Fixed mappings, only the page table structure has to be
+      * created - mappings will be set by set_fixmap():
+      */
+     vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
+     fixrange_init(vaddr, HYPERVISOR_VIRT_START, init_mm.pgd);
+ #if CONFIG_HIGHMEM
+     /*
+      * Permanent kmaps:
+      */
+     vaddr = PKMAP_BASE;
+     fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, init_mm.pgd);
+     pgd = init_mm.pgd + __pgd_offset(vaddr);
+     pmd = pmd_offset(pgd, vaddr);
+     pte = pte_offset(pmd, vaddr);
+     pkmap_page_table = pte;
+ #endif
+ }
+ static void __init zone_sizes_init(void)
+ {
+     unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
+     unsigned int max_dma, high, low;
+     max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+     low = max_low_pfn;
+     high = highend_pfn;
+     if (low < max_dma)
+         zones_size[ZONE_DMA] = low;
+     else {
+         zones_size[ZONE_DMA] = max_dma;
+         zones_size[ZONE_NORMAL] = low - max_dma;
+ #ifdef CONFIG_HIGHMEM
+         zones_size[ZONE_HIGHMEM] = high - low;
+ #endif
+     }
+     free_area_init(zones_size);
+ }
+ void __init paging_init(void)
+ {
+     pagetable_init();
+     zone_sizes_init();
++
+     /* Switch to the real shared_info page, and clear the dummy page. */
+     set_fixmap(FIX_SHARED_INFO, xen_start_info.shared_info);
+     HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
+     memset(empty_zero_page, 0, sizeof(empty_zero_page));
+ #ifdef CONFIG_HIGHMEM
+     kmap_init();
+ #endif
+ }
+ static inline int page_is_ram (unsigned long pagenr)
+ {
+     return 1;
+ }
+ #ifdef CONFIG_HIGHMEM
+ void __init one_highpage_init(struct page *page, int free_page)
+ {
+     ClearPageReserved(page);
+     set_bit(PG_highmem, &page->flags);
+     atomic_set(&page->count, 1);
+     if ( free_page )
+         __free_page(page);
+     totalhigh_pages++;
+ }
+ #endif /* CONFIG_HIGHMEM */
+ static void __init set_max_mapnr_init(void)
+ {
+ #ifdef CONFIG_HIGHMEM
+     highmem_start_page = mem_map + highstart_pfn;
+     max_mapnr = num_physpages = highend_pfn;
+     num_mappedpages = max_low_pfn;
+ #else
+     max_mapnr = num_mappedpages = num_physpages = max_low_pfn;
+ #endif
+ }
+ static int __init free_pages_init(void)
+ {
+ #ifdef CONFIG_HIGHMEM
+     int bad_ppro = 0;
+ #endif
+     int reservedpages, pfn;
+     /* add only boot_pfn pages of low memory to free list.
+      * max_low_pfn may be sized for
+      * pages yet to be allocated from the hypervisor, or it may be set
+      * to override the xen_start_info amount of memory
+      */
+     int boot_pfn = min(xen_start_info.nr_pages,max_low_pfn);
+     /* this will put all low memory onto the freelists */
+     totalram_pages += free_all_bootmem();
+     /* XEN: init and count low-mem pages outside initial allocation. */
+     for (pfn = boot_pfn; pfn < max_low_pfn; pfn++) {
+         ClearPageReserved(&mem_map[pfn]);
+         atomic_set(&mem_map[pfn].count, 1);
+         totalram_pages++;
+     }
+     reservedpages = 0;
+     for (pfn = 0; pfn < boot_pfn ; pfn++) {
+         /*
+          * Only count reserved RAM pages
+          */
+         if (page_is_ram(pfn) && PageReserved(mem_map+pfn))
+             reservedpages++;
+     }
+ #ifdef CONFIG_HIGHMEM
+     for (pfn = highend_pfn-1; pfn >= highstart_pfn; pfn--)
+         one_highpage_init((struct page *) (mem_map + pfn),
+                           (pfn < xen_start_info.nr_pages));
+     totalram_pages += totalhigh_pages;
+ #endif
+     return reservedpages;
+ }
+ void __init mem_init(void)
+ {
+     int codesize, reservedpages, datasize, initsize;
+     if (!mem_map)
+         BUG();
+ #ifdef CONFIG_HIGHMEM
+     /* check that fixmap and pkmap do not overlap */
+     if (PKMAP_BASE+LAST_PKMAP*PAGE_SIZE >= FIXADDR_START) {
+       printk(KERN_ERR "fixmap and kmap areas overlap - this will crash\n");
+       printk(KERN_ERR "pkstart: %lxh pkend: %lxh fixstart %lxh\n",
+              PKMAP_BASE, PKMAP_BASE+LAST_PKMAP*PAGE_SIZE, FIXADDR_START);
+       BUG();
+     }
+ #endif
+     set_max_mapnr_init();
+     high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
+     /* clear the zero-page */
+     memset(empty_zero_page, 0, PAGE_SIZE);
+     reservedpages = free_pages_init();
+     codesize =  (unsigned long) &_etext - (unsigned long) &_text;
+     datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
+     initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
+     printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init, %ldk highmem)\n",
+            (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
+            max_mapnr << (PAGE_SHIFT-10),
+            codesize >> 10,
+            reservedpages << (PAGE_SHIFT-10),
+            datasize >> 10,
+            initsize >> 10,
+            (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))
+         );
+     boot_cpu_data.wp_works_ok = 1;
+ }
+ void free_initmem(void)
+ {
+     unsigned long addr;
+     addr = (unsigned long)(&__init_begin);
+     for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
+         ClearPageReserved(virt_to_page(addr));
+         set_page_count(virt_to_page(addr), 1);
+         free_page(addr);
+         totalram_pages++;
+     }
+     printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
+ }
+ #ifdef CONFIG_BLK_DEV_INITRD
+ void free_initrd_mem(unsigned long start, unsigned long end)
+ {
+     if (start < end)
+         printk (KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+     for (; start < end; start += PAGE_SIZE) {
+         ClearPageReserved(virt_to_page(start));
+         set_page_count(virt_to_page(start), 1);
+         free_page(start);
+         totalram_pages++;
+     }
+ }
+ #endif
+ void si_meminfo(struct sysinfo *val)
+ {
+     val->totalram = max_pfn;
+     val->sharedram = 0;
+     val->freeram = nr_free_pages();
+     val->bufferram = atomic_read(&buffermem_pages);
+     val->totalhigh = max_pfn-max_low_pfn;
+     val->freehigh = nr_free_highpages();
+     val->mem_unit = PAGE_SIZE;
+     return;
+ }
+ #if defined(CONFIG_X86_PAE)
+ struct kmem_cache_s *pae_pgd_cachep;
+ void __init pgtable_cache_init(void)
+ {
+     /*
+      * PAE pgds must be 16-byte aligned:
+        */
+     pae_pgd_cachep = kmem_cache_create("pae_pgd", 32, 0,
+                                        SLAB_HWCACHE_ALIGN | SLAB_MUST_HWCACHE_ALIGN, NULL, NULL);
+     if (!pae_pgd_cachep)
+         panic("init_pae(): Cannot alloc pae_pgd SLAB cache");
+ }
+ #endif /* CONFIG_X86_PAE */
index 0000000000000000000000000000000000000000,34c95c84b55290edb2095f770ee1a472d22889d8..2f3db057d9169e72927be072e4ebf7f9c9a0058e
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,271 +1,266 @@@
 -    mmu_update_t u[MAX_DIRECTMAP_MMU_QUEUE], *w, *v;
 -
 -    u[0].ptr  = MMU_EXTENDED_COMMAND;
 -    u[0].val  = MMUEXT_SET_FOREIGNDOM;
 -    u[0].val |= (unsigned long)domid << 16;
 -    v = w = &u[1];
+ /*
+  * arch/xen/mm/ioremap.c
+  *
+  * Re-map IO memory to kernel address space so that we can access it.
+  *
+  * (C) Copyright 1995 1996 Linus Torvalds
+  *
+  * Modifications for Xenolinux (c) 2003-2004 Keir Fraser
+  */
+ #include <linux/slab.h>
+ #include <linux/mm.h>
+ #include <linux/mman.h>
+ #include <linux/vmalloc.h>
+ #include <asm/io.h>
+ #include <asm/pgalloc.h>
+ #include <asm/uaccess.h>
+ #include <asm/tlb.h>
+ #include <asm/mmu.h>
+ #if defined(CONFIG_XEN_PRIVILEGED_GUEST)
+ /* These hacky macros avoid phys->machine translations. */
+ #define __direct_pte(x) ((pte_t) { (x) } )
+ #define __direct_mk_pte(page_nr,pgprot) \
+   __direct_pte(((page_nr) << PAGE_SHIFT) | pgprot_val(pgprot))
+ #define direct_mk_pte_phys(physpage, pgprot) \
+   __direct_mk_pte((physpage) >> PAGE_SHIFT, pgprot)
+ static inline void direct_remap_area_pte(pte_t *pte, 
+                                         unsigned long address, 
+                                         unsigned long size,
+                                       mmu_update_t **v)
+ {
+     unsigned long end;
+     address &= ~PMD_MASK;
+     end = address + size;
+     if (end > PMD_SIZE)
+         end = PMD_SIZE;
+     if (address >= end)
+         BUG();
+     do {
+         (*v)->ptr = virt_to_machine(pte);
+         (*v)++;
+         address += PAGE_SIZE;
+         pte++;
+     } while (address && (address < end));
+ }
+ static inline int direct_remap_area_pmd(struct mm_struct *mm,
+                                         pmd_t *pmd, 
+                                         unsigned long address, 
+                                         unsigned long size,
+                                       mmu_update_t **v)
+ {
+     unsigned long end;
+     address &= ~PGDIR_MASK;
+     end = address + size;
+     if (end > PGDIR_SIZE)
+         end = PGDIR_SIZE;
+     if (address >= end)
+         BUG();
+     do {
+         pte_t *pte = pte_alloc(mm, pmd, address);
+         if (!pte)
+             return -ENOMEM;
+         direct_remap_area_pte(pte, address, end - address, v);
+         address = (address + PMD_SIZE) & PMD_MASK;
+         pmd++;
+     } while (address && (address < end));
+     return 0;
+ }
+  
+ int __direct_remap_area_pages(struct mm_struct *mm,
+                             unsigned long address, 
+                             unsigned long size, 
+                             mmu_update_t *v)
+ {
+     pgd_t * dir;
+     unsigned long end = address + size;
+     dir = pgd_offset(mm, address);
+     flush_cache_all();
+     if (address >= end)
+         BUG();
+     spin_lock(&mm->page_table_lock);
+     do {
+         pmd_t *pmd = pmd_alloc(mm, dir, address);
+         if (!pmd)
+           return -ENOMEM;
+         direct_remap_area_pmd(mm, pmd, address, end - address, &v);
+         address = (address + PGDIR_SIZE) & PGDIR_MASK;
+         dir++;
+     } while (address && (address < end));
+     spin_unlock(&mm->page_table_lock);
+     flush_tlb_all();
+     return 0;
+ }
+ int direct_remap_area_pages(struct mm_struct *mm,
+                             unsigned long address, 
+                             unsigned long machine_addr,
+                             unsigned long size, 
+                             pgprot_t prot,
+                             domid_t  domid)
+ {
+     int i;
+     unsigned long start_address;
+ #define MAX_DIRECTMAP_MMU_QUEUE 130
 -                                     w);
++    mmu_update_t u[MAX_DIRECTMAP_MMU_QUEUE], *v = u;
+     start_address = address;
+     for( i = 0; i < size; i += PAGE_SIZE )
+     {
+       if ( (v - u) == MAX_DIRECTMAP_MMU_QUEUE )
+       {
+           /* Fill in the PTE pointers. */
+           __direct_remap_area_pages( mm,
+                                      start_address, 
+                                      address-start_address, 
 -          if ( HYPERVISOR_mmu_update(u, v - u, NULL) < 0 )
++                                     u);
+           
 -          v = w;
++          if ( HYPERVISOR_mmu_update(u, v - u, NULL, domid) < 0 )
+               return -EFAULT;     
 -    if ( v != w )
++          v = u;
+           start_address = address;
+       }
+       /*
+          * Fill in the machine address: PTE ptr is done later by
+          * __direct_remap_area_pages(). 
+          */
+         v->val = (machine_addr & PAGE_MASK) | pgprot_val(prot);
+         machine_addr += PAGE_SIZE;
+         address += PAGE_SIZE; 
+         v++;
+     }
 -                                  w);  
 -      if ( unlikely(HYPERVISOR_mmu_update(u, v - u, NULL) < 0) )
++    if ( v != u )
+     {
+       /* get the ptep's filled in */
+       __direct_remap_area_pages(mm,
+                                   start_address, 
+                                   address-start_address, 
++                                  u);  
++      if ( unlikely(HYPERVISOR_mmu_update(u, v - u, NULL, domid) < 0) )
+           return -EFAULT;         
+     }
+     
+     return 0;
+ }
+ #endif /* CONFIG_XEN_PRIVILEGED_GUEST */
+ /*
+  * Remap an arbitrary machine address space into the kernel virtual
+  * address space. Needed when a privileged instance of Xenolinux wants
+  * to access space outside its world directly.
+  *
+  * NOTE! We need to allow non-page-aligned mappings too: we will obviously
+  * have to convert them into an offset in a page-aligned mapping, but the
+  * caller shouldn't need to know that small detail.
+  */
+ void * __ioremap(unsigned long machine_addr, 
+                  unsigned long size, 
+                  unsigned long flags)
+ {
+ #if defined(CONFIG_XEN_PRIVILEGED_GUEST)
+     void * addr;
+     struct vm_struct * area;
+     unsigned long offset, last_addr;
+     pgprot_t prot;
+     /* Don't allow wraparound or zero size */
+     last_addr = machine_addr + size - 1;
+     if (!size || last_addr < machine_addr)
+         return NULL;
+     /* Mappings have to be page-aligned */
+     offset = machine_addr & ~PAGE_MASK;
+     machine_addr &= PAGE_MASK;
+     size = PAGE_ALIGN(last_addr+1) - machine_addr;
+     /* Ok, go for it */
+     area = get_vm_area(size, VM_IOREMAP);
+     if (!area)
+         return NULL;
+     addr = area->addr;
+     prot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | 
+                     _PAGE_ACCESSED | flags);
+     if (direct_remap_area_pages(&init_mm, VMALLOC_VMADDR(addr), 
+                                 machine_addr, size, prot, 0)) {
+         vfree(addr);
+         return NULL;
+     }
+     return (void *) (offset + (char *)addr);
+ #else
+     return NULL;
+ #endif
+ }
+ void iounmap(void *addr)
+ {
+     vfree((void *)((unsigned long)addr & PAGE_MASK));
+ }
+ /* implementation of boot time ioremap for purpose of provising access
+ to the vga console for privileged domains. Unlike boot time ioremap on 
+ other architectures, ours is permanent and not reclaimed when then vmalloc
+ infrastructure is started */
+ void __init *bt_ioremap(unsigned long machine_addr, unsigned long size)
+ {
+         unsigned long offset, last_addr;
+         unsigned int nrpages;
+         enum fixed_addresses idx;
+         /* Don't allow wraparound or zero size */
+         last_addr = machine_addr + size - 1;
+         if (!size || last_addr < machine_addr)
+                 return NULL;
+         /*
+          * Mappings have to be page-aligned
+          */
+         offset = machine_addr & ~PAGE_MASK;
+         machine_addr &= PAGE_MASK;
+         size = PAGE_ALIGN(last_addr) - machine_addr;
+         /*
+          * Mappings have to fit in the FIX_BTMAP area.
+          */
+         nrpages = size >> PAGE_SHIFT;
+         if (nrpages > NR_FIX_BTMAPS)
+                 return NULL;
+         /*
+          * Ok, go for it..
+          */
+         idx = FIX_BTMAP_BEGIN;
+         while (nrpages > 0) {
+                 __set_fixmap(idx, machine_addr, PAGE_KERNEL);
+                 machine_addr += PAGE_SIZE;
+                 --idx;
+                 --nrpages;
+         }
+       flush_tlb_all();
+         return (void*) (offset + fix_to_virt(FIX_BTMAP_BEGIN));
+ }
+ #if 0 /* We don't support these functions. They shouldn't be required. */
+ void __init bt_iounmap(void *addr, unsigned long size) {}
+ #endif
index 0000000000000000000000000000000000000000,33309a9671c5ae84f1691f8587962972d1ad6c84..b59b998d951909b0cdd60bce2bbf3667c60f68b2
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,41 +1,37 @@@
 -    /*
 -     * NB. We load the default_ldt for lcall7/27 handling on demand, as
 -     * it slows down context switching. Noone uses it anyway.
 -     */
 -    queue_set_ldt(0, 0);
+ #ifndef __ARCH_DESC_H
+ #define __ARCH_DESC_H
+ #include <asm/ldt.h>
+ #ifndef __ASSEMBLY__
+ struct desc_struct {
+       unsigned long a,b;
+ };
+ struct Xgt_desc_struct {
+       unsigned short size;
+       unsigned long address __attribute__((packed));
+ };
+ extern struct desc_struct default_ldt[];
+ static inline void clear_LDT(void)
+ {
 -    queue_set_ldt((unsigned long)segments, count);               
++    xen_set_ldt(0, 0);
+ }
+ static inline void load_LDT(mm_context_t *pc)
+ {
+     void *segments = pc->ldt;
+     int count = pc->size;
+     
+     if ( count == 0 )
+         segments = NULL;
+     
++    xen_set_ldt((unsigned long)segments, count);               
+ }
+ #endif /* __ASSEMBLY__ */
+ #endif /* __ARCH_DESC_H__ */
index 0000000000000000000000000000000000000000,bc6e2c2004ea945ea578efdb9984449570ac3130..255ac4a46851e669ce223c96037b44d53028be71
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,105 +1,107 @@@
 -      FIX_GNTTAB,
+ /*
+  * fixmap.h: compile-time virtual memory allocation
+  *
+  * This file is subject to the terms and conditions of the GNU General Public
+  * License.  See the file "COPYING" in the main directory of this archive
+  * for more details.
+  *
+  * Copyright (C) 1998 Ingo Molnar
+  *
+  * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
+  */
+ #ifndef _ASM_FIXMAP_H
+ #define _ASM_FIXMAP_H
+ #include <linux/config.h>
+ #include <linux/kernel.h>
+ #include <asm/apicdef.h>
+ #include <asm/page.h>
++#include <asm-xen/gnttab.h>
+ #ifdef CONFIG_HIGHMEM
+ #include <linux/threads.h>
+ #include <asm/kmap_types.h>
+ #endif
+ /*
+  * Here we define all the compile-time 'special' virtual
+  * addresses. The point is to have a constant address at
+  * compile time, but to set the physical address only
+  * in the boot process. We allocate these special  addresses
+  * from the end of virtual memory (0xfffff000) backwards.
+  * Also this lets us do fail-safe vmalloc(), we
+  * can guarantee that these special addresses and
+  * vmalloc()-ed addresses never overlap.
+  *
+  * these 'compile-time allocated' memory buffers are
+  * fixed-size 4k pages. (or larger if used with an increment
+  * highger than 1) use fixmap_set(idx,phys) to associate
+  * physical memory with fixmap indices.
+  *
+  * TLB entries of such buffers will not be flushed across
+  * task switches.
+  */
+ enum fixed_addresses {
+ #ifdef CONFIG_HIGHMEM
+       FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
+       FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
+ #endif
+       FIX_BLKRING_BASE,
+       FIX_NETRING0_BASE,
+       FIX_NETRING1_BASE,
+       FIX_NETRING2_BASE,
+       FIX_NETRING3_BASE,
+         FIX_SHARED_INFO,
++      FIX_GNTTAB_BEGIN,
++    FIX_GNTTAB_END = FIX_GNTTAB_BEGIN + NR_GRANT_FRAMES - 1,
+ #ifdef CONFIG_VGA_CONSOLE
+ #define NR_FIX_BTMAPS   32  /* 128KB For the Dom0 VGA Console A0000-C0000 */
+ #else
+ #define NR_FIX_BTMAPS   1   /* in case anyone wants it in future... */
+ #endif
+         FIX_BTMAP_END,
+         FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS - 1,
+       /* our bt_ioremap is permanent, unlike other architectures */
+       
+       __end_of_permanent_fixed_addresses,
+       __end_of_fixed_addresses = __end_of_permanent_fixed_addresses
+ };
+ extern void __set_fixmap (enum fixed_addresses idx,
+                                       unsigned long phys, pgprot_t flags);
+ #define set_fixmap(idx, phys) \
+               __set_fixmap(idx, phys, PAGE_KERNEL)
+ /*
+  * Some hardware wants to get fixmapped without caching.
+  */
+ #define set_fixmap_nocache(idx, phys) \
+               __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE)
+ extern void clear_fixmap(enum fixed_addresses idx);
+ /*
+  * used by vmalloc.c.
+  *
+  * Leave one empty page between vmalloc'ed areas and
+  * the start of the fixmap, and leave one page empty
+  * at the top of mem..
+  */
+ #define FIXADDR_TOP   (HYPERVISOR_VIRT_START - 2*PAGE_SIZE)
+ #define __FIXADDR_SIZE        (__end_of_fixed_addresses << PAGE_SHIFT)
+ #define FIXADDR_START (FIXADDR_TOP - __FIXADDR_SIZE)
+ #define __fix_to_virt(x)      (FIXADDR_TOP - ((x) << PAGE_SHIFT))
+ /*
+  * 'index to address' translation. If anyone tries to use the idx
+  * directly without tranlation, we catch the bug with a NULL-deference
+  * kernel oops. Illegal ranges of incoming indices are caught too.
+  */
+ static inline unsigned long fix_to_virt(unsigned int idx)
+ {
+         return __fix_to_virt(idx);
+ }
+ #endif
index 0000000000000000000000000000000000000000,7972ce7d74b3fd8311467b4118aee6d11293ad7c..74004c8d46766a3d77e13bc2cdd6625f0aece5fd
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,74 +1,59 @@@
 -#ifdef CONFIG_SMP
 -              cpu_tlbstate[cpu].state = TLBSTATE_OK;
 -              cpu_tlbstate[cpu].active_mm = next;
 -#endif
 -
+ #ifndef __I386_MMU_CONTEXT_H
+ #define __I386_MMU_CONTEXT_H
+ #include <linux/config.h>
+ #include <asm/desc.h>
+ #include <asm/atomic.h>
+ #include <asm/pgalloc.h>
+ /*
+  * hooks to add arch specific data into the mm struct.
+  * Note that destroy_context is called even if init_new_context
+  * fails.
+  */
+ int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
+ void destroy_context(struct mm_struct *mm);
+ #ifdef CONFIG_SMP
+ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu)
+ {
+       if(cpu_tlbstate[cpu].state == TLBSTATE_OK)
+               cpu_tlbstate[cpu].state = TLBSTATE_LAZY;        
+ }
+ #else
+ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu)
+ {
+ }
+ #endif
+ extern pgd_t *cur_pgd;
+ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk, unsigned cpu)
+ {
++      struct mmuext_op _op[2], *op = _op;
+       if (prev != next) {
+               /* stop flush ipis for the previous mm */
+               clear_bit(cpu, &prev->cpu_vm_mask);
 -              queue_pt_switch(__pa(cur_pgd));
 -                /* load_LDT, if either the previous or next thread
 -                 * has a non-default LDT.
 -                 */
 -                if (next->context.size+prev->context.size)
 -                        load_LDT(&next->context);
 -      }
 -#ifdef CONFIG_SMP
 -      else {
 -              cpu_tlbstate[cpu].state = TLBSTATE_OK;
 -              if(cpu_tlbstate[cpu].active_mm != next)
 -                      out_of_line_bug();
 -              if(!test_and_set_bit(cpu, &next->cpu_vm_mask)) {
 -                      /* We were in lazy tlb mode and leave_mm disabled 
 -                       * tlb flush IPI delivery. We must reload %cr3.
 -                       */
 -                      cur_pgd = next->pgd;
 -                      queue_pt_switch(__pa(cur_pgd));
 -                      load_LDT(next);
+               /* Re-load page tables */
+               cur_pgd = next->pgd;
 -#endif
++              op->cmd = MMUEXT_NEW_BASEPTR;
++              op->mfn = pfn_to_mfn(__pa(next->pgd) >> PAGE_SHIFT);
++              op++;
++              /* load_LDT, if either the previous or next thread
++               * has a non-default LDT.
++               */
++              if (next->context.size+prev->context.size) {
++                      op->cmd = MMUEXT_SET_LDT;
++                      op->linear_addr = (unsigned long)next->context.ldt;
++                      op->nr_ents     = next->context.size;
++                      op++;
+               }
++              BUG_ON(HYPERVISOR_mmuext_op(_op, op-_op, NULL, DOMID_SELF));
+       }
 -#define activate_mm(prev, next) \
 -do { \
 -      switch_mm((prev),(next),NULL,smp_processor_id()); \
 -      flush_page_update_queue(); \
 -} while ( 0 )
+ }
++#define activate_mm(prev, next)       \
++      switch_mm((prev),(next),NULL,smp_processor_id())
+ #endif
index 0000000000000000000000000000000000000000,ca73ccfc31d01be8707a3a1a113405637f769a62..901d9acfc5191c5f0fedee88b29614aeaf07f717
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,182 +1,178 @@@
 -extern unsigned long *phys_to_machine_mapping;
 -#define pfn_to_mfn(_pfn) (phys_to_machine_mapping[(_pfn)])
 -#define mfn_to_pfn(_mfn) (machine_to_phys_mapping[(_mfn)])
+ #ifndef _I386_PAGE_H
+ #define _I386_PAGE_H
+ /* PAGE_SHIFT determines the page size */
+ #define PAGE_SHIFT    12
+ #define PAGE_SIZE     (1UL << PAGE_SHIFT)
+ #define PAGE_MASK     (~(PAGE_SIZE-1))
+ #ifdef __KERNEL__
+ #ifndef __ASSEMBLY__
+ #include <linux/config.h>
+ #include <linux/string.h>
+ #include <asm/types.h>
+ #include <asm-xen/xen-public/xen.h>
+ #ifdef CONFIG_XEN_SCRUB_PAGES
+ #define scrub_pages(_p,_n) memset((void *)(_p), 0, (_n) << PAGE_SHIFT)
+ #else
+ #define scrub_pages(_p,_n) ((void)0)
+ #endif
+ #ifdef CONFIG_X86_USE_3DNOW
+ #include <asm/mmx.h>
+ #define clear_page(page)      mmx_clear_page((void *)(page))
+ #define copy_page(to,from)    mmx_copy_page(to,from)
+ #else
+ /*
+  *    On older X86 processors its not a win to use MMX here it seems.
+  *    Maybe the K6-III ?
+  */
+  
+ #define clear_page(page)      memset((void *)(page), 0, PAGE_SIZE)
+ #define copy_page(to,from)    memcpy((void *)(to), (void *)(from), PAGE_SIZE)
+ #endif
+ #define clear_user_page(page, vaddr)  clear_page(page)
+ #define copy_user_page(to, from, vaddr)       copy_page(to, from)
+ /**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/
 -    if ( (ret & 1) ) ret = machine_to_phys(ret);
++extern unsigned int *phys_to_machine_mapping;
++#define pfn_to_mfn(_pfn) ((unsigned long)(phys_to_machine_mapping[(_pfn)]))
++#define mfn_to_pfn(_mfn) ((unsigned long)(machine_to_phys_mapping[(_mfn)]))
+ static inline unsigned long phys_to_machine(unsigned long phys)
+ {
+     unsigned long machine = pfn_to_mfn(phys >> PAGE_SHIFT);
+     machine = (machine << PAGE_SHIFT) | (phys & ~PAGE_MASK);
+     return machine;
+ }
+ static inline unsigned long machine_to_phys(unsigned long machine)
+ {
+     unsigned long phys = mfn_to_pfn(machine >> PAGE_SHIFT);
+     phys = (phys << PAGE_SHIFT) | (machine & ~PAGE_MASK);
+     return phys;
+ }
+ /*
+  * These are used to make use of C type-checking..
+  */
+ #if CONFIG_X86_PAE
+ typedef struct { unsigned long pte_low, pte_high; } pte_t;
+ typedef struct { unsigned long long pmd; } pmd_t;
+ typedef struct { unsigned long long pgd; } pgd_t;
+ #define pte_val(x)    ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
+ #else
+ typedef struct { unsigned long pte_low; } pte_t;
+ typedef struct { unsigned long pmd; } pmd_t;
+ typedef struct { unsigned long pgd; } pgd_t;
+ static inline unsigned long pte_val(pte_t x)
+ {
+     unsigned long ret = x.pte_low;
+     if ( (ret & 1) ) ret = machine_to_phys(ret);
+     return ret;
+ }
+ #define pte_val_ma(x)   ((x).pte_low)
+ #endif
+ #define PTE_MASK      PAGE_MASK
+ typedef struct { unsigned long pgprot; } pgprot_t;
+ static inline unsigned long pmd_val(pmd_t x)
+ {
+     unsigned long ret = x.pmd;
 -static inline pte_t __pte(unsigned long x)
 -{
 -    if ( (x & 1) ) x = phys_to_machine(x);
 -    return ((pte_t) { (x) });
 -}
 -static inline pmd_t __pmd(unsigned long x)
 -{
 -    if ( (x & 1) ) x = phys_to_machine(x);
 -    return ((pmd_t) { (x) });
 -}
++    if ( ret ) ret = machine_to_phys(ret) | 1;
+     return ret;
+ }
++#define pmd_val_ma(x)   ((x).pmd)
+ #define pgd_val(x)    ({ BUG(); (unsigned long)0; })
+ #define pgprot_val(x) ((x).pgprot)
++#define __pte(x) ({ unsigned long _x = (x); \
++    (((_x)&1) ? ((pte_t) {phys_to_machine(_x)}) : ((pte_t) {(_x)})); })
++#define __pte_ma(x)     ((pte_t) { (x) } )
++#define __pmd(x) ({ unsigned long _x = (x); \
++    (((_x)&1) ? ((pmd_t) {phys_to_machine(_x)}) : ((pmd_t) {(_x)})); })
+ #define __pgd(x) ({ BUG(); (pgprot_t) { 0 }; })
+ #define __pgprot(x)   ((pgprot_t) { (x) } )
+ #endif /* !__ASSEMBLY__ */
+ /* to align the pointer to the (next) page boundary */
+ #define PAGE_ALIGN(addr)      (((addr)+PAGE_SIZE-1)&PAGE_MASK)
+ /*
+  * This handles the memory map.. We could make this a config
+  * option, but too many people screw it up, and too few need
+  * it.
+  *
+  * A __PAGE_OFFSET of 0xC0000000 means that the kernel has
+  * a virtual address space of one gigabyte, which limits the
+  * amount of physical memory you can use to about 950MB. 
+  *
+  * If you want more physical memory than this then see the CONFIG_HIGHMEM4G
+  * and CONFIG_HIGHMEM64G options in the kernel configuration.
+  */
+ #define __PAGE_OFFSET         (0xC0000000)
+ #ifndef __ASSEMBLY__
+ /*
+  * Tell the user there is some problem. Beep too, so we can
+  * see^H^H^Hhear bugs in early bootup as well!
+  * The offending file and line are encoded after the "officially
+  * undefined" opcode for parsing in the trap handler.
+  */
+ #if 1 /* Set to zero for a slightly smaller kernel */
+ #define BUG()                         \
+  __asm__ __volatile__(        "ud2\n"         \
+                       "\t.word %c0\n" \
+                       "\t.long %c1\n" \
+                        : : "i" (__LINE__), "i" (__FILE__))
+ #else
+ #define BUG() __asm__ __volatile__("ud2\n")
+ #endif
+ #define PAGE_BUG(page) do { \
+       BUG(); \
+ } while (0)
+ /* Pure 2^n version of get_order */
+ static __inline__ int get_order(unsigned long size)
+ {
+       int order;
+       size = (size-1) >> (PAGE_SHIFT-1);
+       order = -1;
+       do {
+               size >>= 1;
+               order++;
+       } while (size);
+       return order;
+ }
+ #endif /* __ASSEMBLY__ */
+ #define PAGE_OFFSET           ((unsigned long)__PAGE_OFFSET)
+ #define __pa(x)                       ((unsigned long)(x)-PAGE_OFFSET)
+ #define __va(x)                       ((void *)((unsigned long)(x)+PAGE_OFFSET))
+ #define virt_to_page(kaddr)   (mem_map + (__pa(kaddr) >> PAGE_SHIFT))
+ #define VALID_PAGE(page)      ((page - mem_map) < max_mapnr)
+ #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
+                                VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+ /* VIRT <-> MACHINE conversion */
+ #define virt_to_machine(_a) (phys_to_machine(__pa(_a)))
+ #define machine_to_virt(_m) (__va(machine_to_phys(_m)))
+ #endif /* __KERNEL__ */
+ #endif /* _I386_PAGE_H */
index 0000000000000000000000000000000000000000,f6bee4d6895595670f9f8989430147f295b40648..3f8f38877406b39be1e3854e086aed69b8dacdb9
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,285 +1,280 @@@
 -  XEN_flush_page_update_queue();                 \
+ #ifndef _I386_PGALLOC_H
+ #define _I386_PGALLOC_H
+ #include <linux/config.h>
+ #include <asm/processor.h>
+ #include <asm/fixmap.h>
+ #include <asm/hypervisor.h>
+ #include <linux/threads.h>
+ /*
+  * Quick lists are aligned so that least significant bits of array pointer
+  * are all zero when list is empty, and all one when list is full.
+  */
+ #define QUICKLIST_ENTRIES 256
+ #define QUICKLIST_EMPTY(_l) !((unsigned long)(_l) & ((QUICKLIST_ENTRIES*4)-1))
+ #define QUICKLIST_FULL(_l)  QUICKLIST_EMPTY((_l)+1)
+ #define pgd_quicklist (current_cpu_data.pgd_quick)
+ #define pmd_quicklist (current_cpu_data.pmd_quick)
+ #define pte_quicklist (current_cpu_data.pte_quick)
+ #define pgtable_cache_size (current_cpu_data.pgtable_cache_sz)
+ #define pmd_populate(mm, pmd, pte)              \
+  do {                                             \
+   set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)));   \
 -                __make_page_readonly(pgd);
 -              queue_pgd_pin(__pa(pgd));
+  } while ( 0 )
+ /*
+  * Allocate and free page tables.
+  */
+ #if defined (CONFIG_X86_PAE)
+ #error "no PAE support as yet"
+ /*
+  * We can't include <linux/slab.h> here, thus these uglinesses.
+  */
+ struct kmem_cache_s;
+ extern struct kmem_cache_s *pae_pgd_cachep;
+ extern void *kmem_cache_alloc(struct kmem_cache_s *, int);
+ extern void kmem_cache_free(struct kmem_cache_s *, void *);
+ static inline pgd_t *get_pgd_slow(void)
+ {
+       int i;
+       pgd_t *pgd = kmem_cache_alloc(pae_pgd_cachep, GFP_KERNEL);
+       if (pgd) {
+               for (i = 0; i < USER_PTRS_PER_PGD; i++) {
+                       unsigned long pmd = __get_free_page(GFP_KERNEL);
+                       if (!pmd)
+                               goto out_oom;
+                       clear_page(pmd);
+                       set_pgd(pgd + i, __pgd(1 + __pa(pmd)));
+               }
+               memcpy(pgd + USER_PTRS_PER_PGD,
+                       init_mm.pgd + USER_PTRS_PER_PGD,
+                       (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
+       }
+       return pgd;
+ out_oom:
+       for (i--; i >= 0; i--)
+               free_page((unsigned long)__va(pgd_val(pgd[i])-1));
+       kmem_cache_free(pae_pgd_cachep, pgd);
+       return NULL;
+ }
+ #else
+ static inline pgd_t *get_pgd_slow(void)
+ {
+       pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL);
+       if (pgd) {
+               memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
+               memcpy(pgd + USER_PTRS_PER_PGD,
+                       init_mm.pgd + USER_PTRS_PER_PGD,
+                       (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
 -      queue_pgd_unpin(__pa(pgd));
 -        __make_page_writable(pgd);
++              __make_page_readonly(pgd);
++              xen_pgd_pin(__pa(pgd));
+       }
+       return pgd;
+ }
+ #endif /* CONFIG_X86_PAE */
+ static inline pgd_t *get_pgd_fast(void)
+ {
+       unsigned long ret;
+       if ( !QUICKLIST_EMPTY(pgd_quicklist) ) {
+               ret = *(--pgd_quicklist);
+               pgtable_cache_size--;
+       } else
+               ret = (unsigned long)get_pgd_slow();
+       return (pgd_t *)ret;
+ }
+ static inline void free_pgd_slow(pgd_t *pgd)
+ {
+ #if defined(CONFIG_X86_PAE)
+ #error
+       int i;
+       for (i = 0; i < USER_PTRS_PER_PGD; i++)
+               free_page((unsigned long)__va(pgd_val(pgd[i])-1));
+       kmem_cache_free(pae_pgd_cachep, pgd);
+ #else
 -        queue_pte_pin(__pa(pte));
++      xen_pgd_unpin(__pa(pgd));
++      __make_page_writable(pgd);
+       free_page((unsigned long)pgd);
+ #endif
+ }
+ static inline void free_pgd_fast(pgd_t *pgd)
+ {
+         if ( !QUICKLIST_FULL(pgd_quicklist) ) {
+                 *(pgd_quicklist++) = (unsigned long)pgd;
+                 pgtable_cache_size++;
+         } else
+                 free_pgd_slow(pgd);
+ }
+ static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address)
+ {
+     pte_t *pte;
+     pte = (pte_t *) __get_free_page(GFP_KERNEL);
+     if (pte)
+     {
+         clear_page(pte);
+         __make_page_readonly(pte);
 -    queue_pte_unpin(__pa(pte));
++        xen_pte_pin(__pa(pte));
+     }
+     return pte;
+ }
+ static inline pte_t *pte_alloc_one_fast(struct mm_struct *mm,
+                                       unsigned long address)
+ {
+     unsigned long ret = 0;
+     if ( !QUICKLIST_EMPTY(pte_quicklist) ) {
+         ret = *(--pte_quicklist);
+         pgtable_cache_size--;
+     }
+     return (pte_t *)ret;
+ }
+ static __inline__ void pte_free_slow(pte_t *pte)
+ {
 -      if (mm == current->active_mm) queue_tlb_flush();
 -      XEN_flush_page_update_queue();
++    xen_pte_unpin(__pa(pte));
+     __make_page_writable(pte);
+     free_page((unsigned long)pte);
+ }
+ static inline void pte_free_fast(pte_t *pte)
+ {
+     if ( !QUICKLIST_FULL(pte_quicklist) ) {
+         *(pte_quicklist++) = (unsigned long)pte;
+         pgtable_cache_size++;
+     } else
+         pte_free_slow(pte);
+ }
+ #define pte_free(pte)         pte_free_fast(pte)
+ #define pgd_free(pgd)         free_pgd_fast(pgd)
+ #define pgd_alloc(mm)         get_pgd_fast()
+ /*
+  * allocating and freeing a pmd is trivial: the 1-entry pmd is
+  * inside the pgd, so has no extra memory associated with it.
+  * (In the PAE case we free the pmds as part of the pgd.)
+  */
+ #define pmd_alloc_one_fast(mm, addr)  ({ BUG(); ((pmd_t *)1); })
+ #define pmd_alloc_one(mm, addr)               ({ BUG(); ((pmd_t *)2); })
+ #define pmd_free_slow(x)              do { } while (0)
+ #define pmd_free_fast(x)              do { } while (0)
+ #define pmd_free(x)                   do { } while (0)
+ #define pgd_populate(mm, pmd, pte)    BUG()
+ extern int do_check_pgt_cache(int, int);
+ /*
+  * TLB flushing:
+  *
+  *  - flush_tlb() flushes the current mm struct TLBs
+  *  - flush_tlb_all() flushes all processes TLBs
+  *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
+  *  - flush_tlb_page(vma, vmaddr) flushes one page
+  *  - flush_tlb_range(mm, start, end) flushes a range of pages
+  *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
+  *
+  * ..but the i386 has somewhat limited tlb flushing capabilities,
+  * and page-granular flushes are available only on i486 and up.
+  */
+ #ifndef CONFIG_SMP
+ #define flush_tlb() __flush_tlb()
+ #define flush_tlb_all() __flush_tlb_all()
+ #define local_flush_tlb() __flush_tlb()
+ static inline void flush_tlb_mm(struct mm_struct *mm)
+ {
 -      if (vma->vm_mm == current->active_mm) queue_invlpg(addr);
 -      XEN_flush_page_update_queue();
++      if (mm == current->active_mm) xen_tlb_flush();
+ }
+ static inline void flush_tlb_page(struct vm_area_struct *vma,
+       unsigned long addr)
+ {
 -      if (mm == current->active_mm) queue_tlb_flush();
 -      XEN_flush_page_update_queue();
++      if (vma->vm_mm == current->active_mm) xen_invlpg(addr);
+ }
+ static inline void flush_tlb_range(struct mm_struct *mm,
+       unsigned long start, unsigned long end)
+ {
 -#error no guestos SMP support yet...
++      if (mm == current->active_mm) xen_tlb_flush();
+ }
+ #else
 -    XEN_flush_page_update_queue();
++#error no kernel SMP support yet...
+ #include <asm/smp.h>
+ #define local_flush_tlb() \
+       __flush_tlb()
+ extern void flush_tlb_all(void);
+ extern void flush_tlb_current_task(void);
+ extern void flush_tlb_mm(struct mm_struct *);
+ extern void flush_tlb_page(struct vm_area_struct *, unsigned long);
+ #define flush_tlb()   flush_tlb_current_task()
+ static inline void flush_tlb_range(struct mm_struct * mm, unsigned long start, unsigned long end)
+ {
+       flush_tlb_mm(mm);
+ }
+ #define TLBSTATE_OK   1
+ #define TLBSTATE_LAZY 2
+ struct tlb_state
+ {
+       struct mm_struct *active_mm;
+       int state;
+ } ____cacheline_aligned;
+ extern struct tlb_state cpu_tlbstate[NR_CPUS];
+ #endif /* CONFIG_SMP */
+ static inline void flush_tlb_pgtables(struct mm_struct *mm,
+                                     unsigned long start, unsigned long end)
+ {
+     /* i386 does not keep any page table caches in TLB */
+ }
+ /*
+  * NB. The 'domid' field should be zero if mapping I/O space (non RAM).
+  * Otherwise it identifies the owner of the memory that is being mapped.
+  */
+ extern int direct_remap_area_pages(struct mm_struct *mm,
+                                    unsigned long address, 
+                                    unsigned long machine_addr,
+                                    unsigned long size, 
+                                    pgprot_t prot,
+                                    domid_t  domid);
+ extern int __direct_remap_area_pages(struct mm_struct *mm,
+                                    unsigned long address, 
+                                    unsigned long size, 
+                                    mmu_update_t *v);
+ #endif /* _I386_PGALLOC_H */
index 0000000000000000000000000000000000000000,750ebfeae0360870b5155d8bcbac655725ec2e90..70f8356fb1dbf169f221c7d813b15a605e009c04
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,103 +1,97 @@@
 -#define set_pte(pteptr, pteval) queue_l1_entry_update(pteptr, (pteval).pte_low)
 -#define set_pte_atomic(pteptr, pteval) queue_l1_entry_update(pteptr, (pteval).pte_low)
 -#define set_pmd(pmdptr, pmdval) queue_l2_entry_update((pmdptr), (pmdval))
+ #ifndef _I386_PGTABLE_2LEVEL_H
+ #define _I386_PGTABLE_2LEVEL_H
+ /*
+  * traditional i386 two-level paging structure:
+  */
+ #define PGDIR_SHIFT   22
+ #define PTRS_PER_PGD  1024
+ /*
+  * the i386 is two-level, so we don't really have any
+  * PMD directory physically.
+  */
+ #define PMD_SHIFT     22
+ #define PTRS_PER_PMD  1
+ #define PTRS_PER_PTE  1024
+ #define pte_ERROR(e) \
+       printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, (e).pte_low)
+ #define pmd_ERROR(e) \
+       printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
+ #define pgd_ERROR(e) \
+       printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
+ /*
+  * The "pgd_xxx()" functions here are trivial for a folded two-level
+  * setup: the pgd is never bad, and a pmd always exists (as it's folded
+  * into the pgd entry)
+  */
+ static inline int pgd_none(pgd_t pgd)         { return 0; }
+ static inline int pgd_bad(pgd_t pgd)          { return 0; }
+ static inline int pgd_present(pgd_t pgd)      { return 1; }
+ #define pgd_clear(xp)                         do { } while (0)
 -#define INVALID_P2M_ENTRY (~0UL)
++/*
++ * Certain architectures need to do special things when PTEs
++ * within a page table are directly modified.  Thus, the following
++ * hook is made available.
++ */
++#define set_pte(pteptr, pteval) (*(pteptr) = pteval)
++#define set_pte_atomic(pteptr, pteval) (*(pteptr) = pteval)
++
++/*
++ * (pmds are folded into pgds so this doesnt get actually called,
++ * but the define is needed for a generic inline function.)
++ */
++#define set_pmd(pmdptr, pmdval) xen_l2_entry_update((pmdptr), (pmdval))
+ #define set_pgd(pgdptr, pgdval) ((void)0)
+ #define pgd_page(pgd) \
+ ((unsigned long) __va(pgd_val(pgd) & PAGE_MASK))
+ static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
+ {
+       return (pmd_t *) dir;
+ }
++#define ptep_get_and_clear(xp)        __pte_ma(xchg(&(xp)->pte_low, 0))
+ #define pte_same(a, b)                ((a).pte_low == (b).pte_low)
+ /*                                 
+  * We detect special mappings in one of two ways:
+  *  1. If the MFN is an I/O page then Xen will set the m2p entry
+  *     to be outside our maximum possible pseudophys range.
+  *  2. If the MFN belongs to a different domain then we will certainly
+  *     not have MFN in our p2m table. Conversely, if the page is ours,
+  *     then we'll have p2m(m2p(MFN))==MFN.
+  * If we detect a special mapping then it doesn't have a 'struct page'.
+  * We force !VALID_PAGE() by returning an out-of-range pointer.
+  *
+  * NB. These checks require that, for any MFN that is not in our reservation,
+  * there is no PFN such that p2m(PFN) == MFN. Otherwise we can get confused if
+  * we are foreign-mapping the MFN, and the other domain as m2p(MFN) == PFN.
+  * Yikes! Various places must poke in INVALID_P2M_ENTRY for safety.
+  * 
+  * NB2. When deliberately mapping foreign pages into the p2m table, you *must*
+  *      use FOREIGN_FRAME(). This will cause pte_pfn() to choke on it, as we
+  *      require. In all the cases we care about, the high bit gets shifted out
+  *      (e.g., phys_to_machine()) so behaviour there is correct.
+  */
 -/*
 - * A note on implementation of this atomic 'get-and-clear' operation.
 - * This is actually very simple because XenoLinux can only run on a single
 - * processor. Therefore, we cannot race other processors setting the 'accessed'
 - * or 'dirty' bits on a page-table entry.
 - * Even if pages are shared between domains, that is not a problem because
 - * each domain will have separate page tables, with their own versions of
 - * accessed & dirty state.
 - */
 -static inline pte_t ptep_get_and_clear(pte_t *xp)
 -{
 -    pte_t pte = *xp;
 -    if ( !pte_none(pte) )
 -        queue_l1_entry_update(xp, 0);
 -    return pte;
 -}
 -
++#define INVALID_P2M_ENTRY (~0U)
+ #define FOREIGN_FRAME(_m) ((_m) | (1UL<<((sizeof(unsigned long)*8)-1)))
+ #define pte_page(_pte)                                        \
+ ({                                                            \
+     unsigned long mfn = (_pte).pte_low >> PAGE_SHIFT;         \
+     unsigned long pfn = mfn_to_pfn(mfn);                      \
+     if ( (pfn >= max_mapnr) || (pfn_to_mfn(pfn) != mfn) )     \
+         pfn = max_mapnr; /* specia: force !VALID_PAGE() */    \
+     &mem_map[pfn];                                            \
+ })
+ #define pte_none(x)           (!(x).pte_low)
+ #define __mk_pte(page_nr,pgprot) __pte(((page_nr) << PAGE_SHIFT) | pgprot_val(pgprot))
+ #endif /* _I386_PGTABLE_2LEVEL_H */
index 0000000000000000000000000000000000000000,c15f0e9509b4e480e980bc0f43e933bafd613392..19947a9aaebf340efd0cd89aaf332b791cf1e8e0
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,370 +1,371 @@@
 -#define __flush_tlb() ({ queue_tlb_flush(); XEN_flush_page_update_queue(); })
+ #ifndef _I386_PGTABLE_H
+ #define _I386_PGTABLE_H
+ #include <linux/config.h>
+ /*
+  * The Linux memory management assumes a three-level page table setup. On
+  * the i386, we use that, but "fold" the mid level into the top-level page
+  * table, so that we physically have the same two-level page table as the
+  * i386 mmu expects.
+  *
+  * This file contains the functions and defines necessary to modify and use
+  * the i386 page table tree.
+  */
+ #ifndef __ASSEMBLY__
+ #include <asm/processor.h>
+ #include <asm/hypervisor.h>
+ #include <linux/threads.h>
+ #include <asm/fixmap.h>
+ #ifndef _I386_BITOPS_H
+ #include <asm/bitops.h>
+ #endif
+ #define swapper_pg_dir 0
+ extern void paging_init(void);
+ /* Caches aren't brain-dead on the intel. */
+ #define flush_cache_all()                     do { } while (0)
+ #define flush_cache_mm(mm)                    do { } while (0)
+ #define flush_cache_range(mm, start, end)     do { } while (0)
+ #define flush_cache_page(vma, vmaddr)         do { } while (0)
+ #define flush_page_to_ram(page)                       do { } while (0)
+ #define flush_dcache_page(page)                       do { } while (0)
+ #define flush_icache_range(start, end)                do { } while (0)
+ #define flush_icache_page(vma,pg)             do { } while (0)
+ #define flush_icache_user_range(vma,pg,adr,len)       do { } while (0)
+ extern unsigned long pgkern_mask;
 -#define __flush_tlb_one(addr) ({ queue_invlpg(addr); XEN_flush_page_update_queue(); })
 -#define __flush_tlb_single(addr) ({ queue_invlpg(addr); XEN_flush_page_update_queue(); })
++#define __flush_tlb() xen_tlb_flush()
+ #define __flush_tlb_global() __flush_tlb()
+ #define __flush_tlb_all() __flush_tlb_global()
 -#define pte_clear(xp) queue_l1_entry_update(xp, 0)
++#define __flush_tlb_one(addr) xen_invlpg(addr)
++#define __flush_tlb_single(addr) xen_invlpg(addr)
+ /*
+  * ZERO_PAGE is a global shared page that is always zero: used
+  * for zero-mapped memory areas etc..
+  */
+ extern unsigned long empty_zero_page[1024];
+ #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
+ #endif /* !__ASSEMBLY__ */
+ /*
+  * The Linux x86 paging architecture is 'compile-time dual-mode', it
+  * implements both the traditional 2-level x86 page tables and the
+  * newer 3-level PAE-mode page tables.
+  */
+ #ifndef __ASSEMBLY__
+ #if CONFIG_X86_PAE
+ # include <asm/pgtable-3level.h>
+ /*
+  * Need to initialise the X86 PAE caches
+  */
+ extern void pgtable_cache_init(void);
+ #else
+ # include <asm/pgtable-2level.h>
+ /*
+  * No page table caches to initialise
+  */
+ #define pgtable_cache_init()  do { } while (0)
+ #endif
+ #endif
+ #define PMD_SIZE      (1UL << PMD_SHIFT)
+ #define PMD_MASK      (~(PMD_SIZE-1))
+ #define PGDIR_SIZE    (1UL << PGDIR_SHIFT)
+ #define PGDIR_MASK    (~(PGDIR_SIZE-1))
+ #define USER_PTRS_PER_PGD     (TASK_SIZE/PGDIR_SIZE)
+ #define FIRST_USER_PGD_NR     0
+ #define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
+ #define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
+ #define TWOLEVEL_PGDIR_SHIFT  22
+ #define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT)
+ #define BOOT_KERNEL_PGD_PTRS (1024-BOOT_USER_PGD_PTRS)
+ #ifndef __ASSEMBLY__
+ /* 4MB is just a nice "safety zone". Also, we align to a fresh pde. */
+ #define VMALLOC_OFFSET        (4*1024*1024)
+ extern void * high_memory;
+ #define VMALLOC_START (((unsigned long) high_memory + 2*VMALLOC_OFFSET-1) & \
+                                               ~(VMALLOC_OFFSET-1))
+ #define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #if CONFIG_HIGHMEM
+ # define VMALLOC_END  (PKMAP_BASE-2*PAGE_SIZE)
+ #else
+ # define VMALLOC_END  (FIXADDR_START-2*PAGE_SIZE)
+ #endif
+ #define _PAGE_BIT_PRESENT     0
+ #define _PAGE_BIT_RW          1
+ #define _PAGE_BIT_USER                2
+ #define _PAGE_BIT_PWT         3
+ #define _PAGE_BIT_PCD         4
+ #define _PAGE_BIT_ACCESSED    5
+ #define _PAGE_BIT_DIRTY               6
+ #define _PAGE_BIT_PSE         7       /* 4 MB (or 2MB) page, Pentium+, if present.. */
+ #define _PAGE_BIT_GLOBAL      8       /* Global TLB entry PPro+ */
+ #define _PAGE_PRESENT 0x001
+ #define _PAGE_RW      0x002
+ #define _PAGE_USER    0x004
+ #define _PAGE_PWT     0x008
+ #define _PAGE_PCD     0x010
+ #define _PAGE_ACCESSED        0x020
+ #define _PAGE_DIRTY   0x040
+ #define _PAGE_PSE     0x080   /* 4 MB (or 2MB) page, Pentium+, if present.. */
+ #define _PAGE_GLOBAL  0x100   /* Global TLB entry PPro+ */
+ #define _PAGE_PROTNONE        0x080   /* If not present */
+ #define _PAGE_TABLE   (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
+ #define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
+ #define _PAGE_CHG_MASK        (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
+ #define PAGE_NONE     __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
+ #define PAGE_SHARED   __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
+ #define PAGE_COPY     __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
+ #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
+ #define __PAGE_KERNEL \
+       (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
+ #define __PAGE_KERNEL_NOCACHE \
+       (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_PCD | _PAGE_ACCESSED)
+ #define __PAGE_KERNEL_RO \
+       (_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED)
+ #if 0
+ #define MAKE_GLOBAL(x) __pgprot((x) | _PAGE_GLOBAL)
+ #else
+ #define MAKE_GLOBAL(x) __pgprot(x)
+ #endif
+ #define PAGE_KERNEL MAKE_GLOBAL(__PAGE_KERNEL)
+ #define PAGE_KERNEL_RO MAKE_GLOBAL(__PAGE_KERNEL_RO)
+ #define PAGE_KERNEL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE)
+ /*
+  * The i386 can't do page protection for execute, and considers that
+  * the same are read. Also, write permissions imply read permissions.
+  * This is the closest we can get..
+  */
+ #define __P000        PAGE_NONE
+ #define __P001        PAGE_READONLY
+ #define __P010        PAGE_COPY
+ #define __P011        PAGE_COPY
+ #define __P100        PAGE_READONLY
+ #define __P101        PAGE_READONLY
+ #define __P110        PAGE_COPY
+ #define __P111        PAGE_COPY
+ #define __S000        PAGE_NONE
+ #define __S001        PAGE_READONLY
+ #define __S010        PAGE_SHARED
+ #define __S011        PAGE_SHARED
+ #define __S100        PAGE_READONLY
+ #define __S101        PAGE_READONLY
+ #define __S110        PAGE_SHARED
+ #define __S111        PAGE_SHARED
+ #define pte_present(x)        ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))
 -#define pmd_none(x)   (!(x).pmd)
 -#define pmd_present(x)        ((x).pmd & _PAGE_PRESENT)
++#define pte_clear(xp) do { set_pte(xp, __pte(0)); } while (0)
 -#define       pmd_bad(x)      (((x).pmd & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
++#define pmd_none(x)   (!pmd_val(x))
++/* pmd_present doesn't just test the _PAGE_PRESENT bit since wr.p.t.
++   can temporarily clear it. */
++#define pmd_present(x)        (pmd_val(x))
+ #define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0)
 -    unsigned long pteval = *(unsigned long *)ptep;
 -    int ret = pteval & _PAGE_DIRTY;
 -    if ( ret ) queue_l1_entry_update(ptep, pteval & ~_PAGE_DIRTY);
 -    return ret;
++#define pmd_bad(x)    ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER & ~_PAGE_PRESENT)) != (_KERNPG_TABLE & ~_PAGE_PRESENT))
+ #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
+ /*
+  * The following only work if pte_present() is true.
+  * Undefined behaviour if not..
+  */
+ static inline int pte_read(pte_t pte)         { return (pte).pte_low & _PAGE_USER; }
+ static inline int pte_exec(pte_t pte)         { return (pte).pte_low & _PAGE_USER; }
+ static inline int pte_dirty(pte_t pte)                { return (pte).pte_low & _PAGE_DIRTY; }
+ static inline int pte_young(pte_t pte)                { return (pte).pte_low & _PAGE_ACCESSED; }
+ static inline int pte_write(pte_t pte)                { return (pte).pte_low & _PAGE_RW; }
+ static inline pte_t pte_rdprotect(pte_t pte)  { (pte).pte_low &= ~_PAGE_USER; return pte; }
+ static inline pte_t pte_exprotect(pte_t pte)  { (pte).pte_low &= ~_PAGE_USER; return pte; }
+ static inline pte_t pte_mkclean(pte_t pte)    { (pte).pte_low &= ~_PAGE_DIRTY; return pte; }
+ static inline pte_t pte_mkold(pte_t pte)      { (pte).pte_low &= ~_PAGE_ACCESSED; return pte; }
+ static inline pte_t pte_wrprotect(pte_t pte)  { (pte).pte_low &= ~_PAGE_RW; return pte; }
+ static inline pte_t pte_mkread(pte_t pte)     { (pte).pte_low |= _PAGE_USER; return pte; }
+ static inline pte_t pte_mkexec(pte_t pte)     { (pte).pte_low |= _PAGE_USER; return pte; }
+ static inline pte_t pte_mkdirty(pte_t pte)    { (pte).pte_low |= _PAGE_DIRTY; return pte; }
+ static inline pte_t pte_mkyoung(pte_t pte)    { (pte).pte_low |= _PAGE_ACCESSED; return pte; }
+ static inline pte_t pte_mkwrite(pte_t pte)    { (pte).pte_low |= _PAGE_RW; return pte; }
+ static inline int ptep_test_and_clear_dirty(pte_t *ptep)
+ {
 -static inline  int ptep_test_and_clear_young(pte_t *ptep)
++    if (!pte_dirty(*ptep))
++        return 0;
++    return test_and_clear_bit(_PAGE_BIT_DIRTY, &ptep->pte_low);
+ }
 -    unsigned long pteval = *(unsigned long *)ptep;
 -    int ret = pteval & _PAGE_ACCESSED;
 -    if ( ret ) queue_l1_entry_update(ptep, pteval & ~_PAGE_ACCESSED);
 -    return ret;
++
++static inline int ptep_test_and_clear_young(pte_t *ptep)
+ {
 -    unsigned long pteval = *(unsigned long *)ptep;
 -    if ( (pteval & _PAGE_RW) )
 -        queue_l1_entry_update(ptep, pteval & ~_PAGE_RW);
++    if (!pte_young(*ptep))
++        return 0;
++    return test_and_clear_bit(_PAGE_BIT_ACCESSED, &ptep->pte_low);
+ }
++
+ static inline void ptep_set_wrprotect(pte_t *ptep)
+ {
 -    unsigned long pteval = *(unsigned long *)ptep;
 -    if ( !(pteval & _PAGE_DIRTY) )
 -        queue_l1_entry_update(ptep, pteval | _PAGE_DIRTY);
++    if (pte_write(*ptep))
++        clear_bit(_PAGE_BIT_RW, &ptep->pte_low);
+ }
++
+ static inline void ptep_mkdirty(pte_t *ptep)
+ {
 -    queue_l1_entry_update(pte, (*(unsigned long *)pte)&~_PAGE_RW);
++    if (!pte_dirty(*ptep))
++        set_bit(_PAGE_BIT_DIRTY, &ptep->pte_low);
+ }
+ /*
+  * Conversion functions: convert a page and protection to a page entry,
+  * and a page entry and page directory to the page they refer to.
+  */
+ #define mk_pte(page, pgprot)  __mk_pte((page) - mem_map, (pgprot))
+ /* This takes a physical page address that is used by the remapping functions */
+ #define mk_pte_phys(physpage, pgprot) __mk_pte((physpage) >> PAGE_SHIFT, pgprot)
+ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+ {
+       pte.pte_low &= _PAGE_CHG_MASK;
+       pte.pte_low |= pgprot_val(newprot);
+       return pte;
+ }
+ #define page_pte(page) page_pte_prot(page, __pgprot(0))
+ #define pmd_page(pmd) \
+ ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
+ /* to find an entry in a page-table-directory. */
+ #define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
+ #define __pgd_offset(address) pgd_index(address)
+ #define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address))
+ /* to find an entry in a kernel page-table-directory */
+ #define pgd_offset_k(address) pgd_offset(&init_mm, address)
+ #define __pmd_offset(address) \
+               (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
+ /* Find an entry in the third-level page table.. */
+ #define __pte_offset(address) \
+               ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+ #define pte_offset(dir, address) ((pte_t *) pmd_page(*(dir)) + \
+                       __pte_offset(address))
+ /*
+  * The i386 doesn't have any external MMU info: the kernel page
+  * tables contain all the necessary information.
+  */
+ #define update_mmu_cache(vma,address,pte) do { } while (0)
+ /* Encode and de-code a swap entry */
+ #define SWP_TYPE(x)                   (((x).val >> 1) & 0x3f)
+ #define SWP_OFFSET(x)                 ((x).val >> 8)
+ #define SWP_ENTRY(type, offset)               ((swp_entry_t) { ((type) << 1) | ((offset) << 8) })
+ #define pte_to_swp_entry(pte)         ((swp_entry_t) { (pte).pte_low })
+ #define swp_entry_to_pte(x)           ((pte_t) { (x).val })
+ struct page;
+ int change_page_attr(struct page *, int, pgprot_t prot);
+ static inline void __make_page_readonly(void *va)
+ {
+     pgd_t *pgd = pgd_offset_k((unsigned long)va);
+     pmd_t *pmd = pmd_offset(pgd, (unsigned long)va);
+     pte_t *pte = pte_offset(pmd, (unsigned long)va);
 -    queue_l1_entry_update(pte, (*(unsigned long *)pte)|_PAGE_RW);
++    set_pte(pte, pte_wrprotect(*pte));
+ }
+ static inline void __make_page_writable(void *va)
+ {
+     pgd_t *pgd = pgd_offset_k((unsigned long)va);
+     pmd_t *pmd = pmd_offset(pgd, (unsigned long)va);
+     pte_t *pte = pte_offset(pmd, (unsigned long)va);
 -    queue_l1_entry_update(pte, (*(unsigned long *)pte)&~_PAGE_RW);
++    set_pte(pte, pte_mkwrite(*pte));
+ }
+ static inline void make_page_readonly(void *va)
+ {
+     pgd_t *pgd = pgd_offset_k((unsigned long)va);
+     pmd_t *pmd = pmd_offset(pgd, (unsigned long)va);
+     pte_t *pte = pte_offset(pmd, (unsigned long)va);
 -    queue_l1_entry_update(pte, (*(unsigned long *)pte)|_PAGE_RW);
++    set_pte(pte, pte_wrprotect(*pte));
+     if ( (unsigned long)va >= VMALLOC_START )
+         __make_page_readonly(machine_to_virt(
+             *(unsigned long *)pte&PAGE_MASK));
+ }
+ static inline void make_page_writable(void *va)
+ {
+     pgd_t *pgd = pgd_offset_k((unsigned long)va);
+     pmd_t *pmd = pmd_offset(pgd, (unsigned long)va);
+     pte_t *pte = pte_offset(pmd, (unsigned long)va);
++    set_pte(pte, pte_mkwrite(*pte));
+     if ( (unsigned long)va >= VMALLOC_START )
+         __make_page_writable(machine_to_virt(
+             *(unsigned long *)pte&PAGE_MASK));
+ }
+ static inline void make_pages_readonly(void *va, unsigned int nr)
+ {
+     while ( nr-- != 0 )
+     {
+         make_page_readonly(va);
+         va = (void *)((unsigned long)va + PAGE_SIZE);
+     }
+ }
+ static inline void make_pages_writable(void *va, unsigned int nr)
+ {
+     while ( nr-- != 0 )
+     {
+         make_page_writable(va);
+         va = (void *)((unsigned long)va + PAGE_SIZE);
+     }
+ }
+ static inline unsigned long arbitrary_virt_to_machine(void *va)
+ {
+     pgd_t *pgd = pgd_offset_k((unsigned long)va);
+     pmd_t *pmd = pmd_offset(pgd, (unsigned long)va);
+     pte_t *pte = pte_offset(pmd, (unsigned long)va);
+     unsigned long pa = (*(unsigned long *)pte) & PAGE_MASK;
+     return pa | ((unsigned long)va & (PAGE_SIZE-1));
+ }
+ #endif /* !__ASSEMBLY__ */
+ /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
+ #define PageSkip(page)                (0)
+ #define kern_addr_valid(addr) (1)
+ #define io_remap_page_range remap_page_range
+ #endif /* _I386_PGTABLE_H */
index 0000000000000000000000000000000000000000,fda33efd3a7579b83b9a1824bc47b7e72fc4ef26..f694674233e8d5721a74ed849ee18f6a85b2c768
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,424 +1,424 @@@
 -#define stts() (HYPERVISOR_fpu_taskswitch())
+ #ifndef __ASM_SYSTEM_H
+ #define __ASM_SYSTEM_H
+ #include <linux/config.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/bitops.h>
+ #include <asm/synch_bitops.h>
+ #include <asm/segment.h>
+ #include <asm/hypervisor.h>
+ #include <asm/evtchn.h>
+ #ifdef __KERNEL__
+ struct task_struct;
+ extern void FASTCALL(__switch_to(struct task_struct *prev, 
+                                  struct task_struct *next));
+ #define prepare_to_switch()                                             \
+ do {                                                                    \
+     struct thread_struct *__t = &current->thread;                       \
+     __asm__ __volatile__ ( "movl %%fs,%0" : "=m" (*(int *)&__t->fs) );  \
+     __asm__ __volatile__ ( "movl %%gs,%0" : "=m" (*(int *)&__t->gs) );  \
+ } while (0)
+ #define switch_to(prev,next,last) do {                                        \
+       asm volatile("pushl %%esi\n\t"                                  \
+                    "pushl %%edi\n\t"                                  \
+                    "pushl %%ebp\n\t"                                  \
+                    "movl %%esp,%0\n\t"        /* save ESP */          \
+                    "movl %3,%%esp\n\t"        /* restore ESP */       \
+                    "movl $1f,%1\n\t"          /* save EIP */          \
+                    "pushl %4\n\t"             /* restore EIP */       \
+                    "jmp __switch_to\n"                                \
+                    "1:\t"                                             \
+                    "popl %%ebp\n\t"                                   \
+                    "popl %%edi\n\t"                                   \
+                    "popl %%esi\n\t"                                   \
+                    :"=m" (prev->thread.esp),"=m" (prev->thread.eip),  \
+                     "=b" (last)                                       \
+                    :"m" (next->thread.esp),"m" (next->thread.eip),    \
+                     "a" (prev), "d" (next),                           \
+                     "b" (prev));                                      \
+ } while (0)
+ #define _set_base(addr,base) do { unsigned long __pr; \
+ __asm__ __volatile__ ("movw %%dx,%1\n\t" \
+       "rorl $16,%%edx\n\t" \
+       "movb %%dl,%2\n\t" \
+       "movb %%dh,%3" \
+       :"=&d" (__pr) \
+       :"m" (*((addr)+2)), \
+        "m" (*((addr)+4)), \
+        "m" (*((addr)+7)), \
+          "0" (base) \
+         ); } while(0)
+ #define _set_limit(addr,limit) do { unsigned long __lr; \
+ __asm__ __volatile__ ("movw %%dx,%1\n\t" \
+       "rorl $16,%%edx\n\t" \
+       "movb %2,%%dh\n\t" \
+       "andb $0xf0,%%dh\n\t" \
+       "orb %%dh,%%dl\n\t" \
+       "movb %%dl,%2" \
+       :"=&d" (__lr) \
+       :"m" (*(addr)), \
+        "m" (*((addr)+6)), \
+        "0" (limit) \
+         ); } while(0)
+ #define set_base(ldt,base) _set_base( ((char *)&(ldt)) , (base) )
+ #define set_limit(ldt,limit) _set_limit( ((char *)&(ldt)) , ((limit)-1)>>12 )
+ static inline unsigned long _get_base(char * addr)
+ {
+       unsigned long __base;
+       __asm__("movb %3,%%dh\n\t"
+               "movb %2,%%dl\n\t"
+               "shll $16,%%edx\n\t"
+               "movw %1,%%dx"
+               :"=&d" (__base)
+               :"m" (*((addr)+2)),
+                "m" (*((addr)+4)),
+                "m" (*((addr)+7)));
+       return __base;
+ }
+ #define get_base(ldt) _get_base( ((char *)&(ldt)) )
+ /*
+  * Load a segment. Fall back on loading the zero
+  * segment if something goes wrong..
+  */
+ #define loadsegment(seg,value)                        \
+       asm volatile("\n"                       \
+               "1:\t"                          \
+               "movl %0,%%" #seg "\n"          \
+               "2:\n"                          \
+               ".section .fixup,\"ax\"\n"      \
+               "3:\t"                          \
+               "pushl $0\n\t"                  \
+               "popl %%" #seg "\n\t"           \
+               "jmp 2b\n"                      \
+               ".previous\n"                   \
+               ".section __ex_table,\"a\"\n\t" \
+               ".align 4\n\t"                  \
+               ".long 1b,3b\n"                 \
+               ".previous"                     \
+               : :"m" (*(unsigned int *)&(value)))
+ /* NB. 'clts' is done for us by Xen during virtual trap. */
+ #define clts() ((void)0)
++#define stts() (HYPERVISOR_fpu_taskswitch(1))
+ #endif        /* __KERNEL__ */
+ /**
+  * __ffs - find first bit in word.
+  * @word: The word to search
+  *
+  * Undefined if no bit exists, so code should check against 0 first.
+  *
+  * Taken from 2.6 for Xen.
+  */
+ static inline unsigned long __ffs(unsigned long word)
+ {
+       __asm__("bsfl %1,%0"
+               :"=r" (word)
+               :"rm" (word));
+       return word;
+ }
+ static inline unsigned long get_limit(unsigned long segment)
+ {
+       unsigned long __limit;
+       __asm__("lsll %1,%0"
+               :"=r" (__limit):"r" (segment));
+       return __limit+1;
+ }
+ #define nop() __asm__ __volatile__ ("nop")
+ #define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
+ #define tas(ptr) (xchg((ptr),1))
+ struct __xchg_dummy { unsigned long a[100]; };
+ #define __xg(x) ((struct __xchg_dummy *)(x))
+ /*
+  * The semantics of XCHGCMP8B are a bit strange, this is why
+  * there is a loop and the loading of %%eax and %%edx has to
+  * be inside. This inlines well in most cases, the cached
+  * cost is around ~38 cycles. (in the future we might want
+  * to do an SIMD/3DNOW!/MMX/FPU 64-bit store here, but that
+  * might have an implicit FPU-save as a cost, so it's not
+  * clear which path to go.)
+  *
+  * chmxchg8b must be used with the lock prefix here to allow
+  * the instruction to be executed atomically, see page 3-102
+  * of the instruction set reference 24319102.pdf. We need
+  * the reader side to see the coherent 64bit value.
+  */
+ static inline void __set_64bit (unsigned long long * ptr,
+               unsigned int low, unsigned int high)
+ {
+       __asm__ __volatile__ (
+               "\n1:\t"
+               "movl (%0), %%eax\n\t"
+               "movl 4(%0), %%edx\n\t"
+               "lock cmpxchg8b (%0)\n\t"
+               "jnz 1b"
+               : /* no outputs */
+               :       "D"(ptr),
+                       "b"(low),
+                       "c"(high)
+               :       "ax","dx","memory");
+ }
+ static inline void __set_64bit_constant (unsigned long long *ptr,
+                                                unsigned long long value)
+ {
+       __set_64bit(ptr,(unsigned int)(value), (unsigned int)((value)>>32ULL));
+ }
+ #define ll_low(x)     *(((unsigned int*)&(x))+0)
+ #define ll_high(x)    *(((unsigned int*)&(x))+1)
+ static inline void __set_64bit_var (unsigned long long *ptr,
+                        unsigned long long value)
+ {
+       __set_64bit(ptr,ll_low(value), ll_high(value));
+ }
+ #define set_64bit(ptr,value) \
+ (__builtin_constant_p(value) ? \
+  __set_64bit_constant(ptr, value) : \
+  __set_64bit_var(ptr, value) )
+ #define _set_64bit(ptr,value) \
+ (__builtin_constant_p(value) ? \
+  __set_64bit(ptr, (unsigned int)(value), (unsigned int)((value)>>32ULL) ) : \
+  __set_64bit(ptr, ll_low(value), ll_high(value)) )
+ /*
+  * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
+  * Note 2: xchg has side effect, so that attribute volatile is necessary,
+  *      but generally the primitive is invalid, *ptr is output argument. --ANK
+  */
+ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
+ {
+       switch (size) {
+               case 1:
+                       __asm__ __volatile__("xchgb %b0,%1"
+                               :"=q" (x)
+                               :"m" (*__xg(ptr)), "0" (x)
+                               :"memory");
+                       break;
+               case 2:
+                       __asm__ __volatile__("xchgw %w0,%1"
+                               :"=r" (x)
+                               :"m" (*__xg(ptr)), "0" (x)
+                               :"memory");
+                       break;
+               case 4:
+                       __asm__ __volatile__("xchgl %0,%1"
+                               :"=r" (x)
+                               :"m" (*__xg(ptr)), "0" (x)
+                               :"memory");
+                       break;
+       }
+       return x;
+ }
+ /*
+  * Atomic compare and exchange.  Compare OLD with MEM, if identical,
+  * store NEW in MEM.  Return the initial value in MEM.  Success is
+  * indicated by comparing RETURN with OLD.
+  */
+ #ifdef CONFIG_X86_CMPXCHG
+ #define __HAVE_ARCH_CMPXCHG 1
+ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
+                                     unsigned long new, int size)
+ {
+       unsigned long prev;
+       switch (size) {
+       case 1:
+               __asm__ __volatile__("lock cmpxchgb %b1,%2"
+                                    : "=a"(prev)
+                                    : "q"(new), "m"(*__xg(ptr)), "0"(old)
+                                    : "memory");
+               return prev;
+       case 2:
+               __asm__ __volatile__("lock cmpxchgw %w1,%2"
+                                    : "=a"(prev)
+                                    : "q"(new), "m"(*__xg(ptr)), "0"(old)
+                                    : "memory");
+               return prev;
+       case 4:
+               __asm__ __volatile__("lock cmpxchgl %1,%2"
+                                    : "=a"(prev)
+                                    : "q"(new), "m"(*__xg(ptr)), "0"(old)
+                                    : "memory");
+               return prev;
+       }
+       return old;
+ }
+ #define cmpxchg(ptr,o,n)\
+       ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
+                                       (unsigned long)(n),sizeof(*(ptr))))
+     
+ #else
+ /* Compiling for a 386 proper.        Is it worth implementing via cli/sti?  */
+ #endif
+ /*
+  * Force strict CPU ordering.
+  * And yes, this is required on UP too when we're talking
+  * to devices.
+  *
+  * For now, "wmb()" doesn't actually do anything, as all
+  * Intel CPU's follow what Intel calls a *Processor Order*,
+  * in which all writes are seen in the program order even
+  * outside the CPU.
+  *
+  * I expect future Intel CPU's to have a weaker ordering,
+  * but I'd also expect them to finally get their act together
+  * and add some real memory barriers if so.
+  *
+  * Some non intel clones support out of order store. wmb() ceases to be a
+  * nop for these.
+  */
+  
+ #define mb()  __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
+ #define rmb() mb()
+ #ifdef CONFIG_X86_OOSTORE
+ #define wmb()         __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
+ #else
+ #define wmb() __asm__ __volatile__ ("": : :"memory")
+ #endif
+ #ifdef CONFIG_SMP
+ #define smp_mb()      mb()
+ #define smp_rmb()     rmb()
+ #define smp_wmb()     wmb()
+ #define set_mb(var, value) do { xchg(&var, value); } while (0)
+ #else
+ #define smp_mb()      barrier()
+ #define smp_rmb()     barrier()
+ #define smp_wmb()     barrier()
+ #define set_mb(var, value) do { var = value; barrier(); } while (0)
+ #endif
+ #define set_wmb(var, value) do { var = value; wmb(); } while (0)
+ #define safe_halt()             ((void)0)
+ /* 
+  * The use of 'barrier' in the following reflects their use as local-lock
+  * operations. Reentrancy must be prevented (e.g., __cli()) /before/ following
+  * critical operations are executed. All critical operatiosn must complete
+  * /before/ reentrancy is permitted (e.g., __sti()). Alpha architecture also
+  * includes these barriers, for example.
+  */
+ #define __cli()                                                               \
+ do {                                                                          \
+     HYPERVISOR_shared_info->vcpu_data[0].evtchn_upcall_mask = 1;              \
+     barrier();                                                                \
+ } while (0)
+ #define __sti()                                                               \
+ do {                                                                          \
+     shared_info_t *_shared = HYPERVISOR_shared_info;                          \
+     barrier();                                                                \
+     _shared->vcpu_data[0].evtchn_upcall_mask = 0;                             \
+     barrier(); /* unmask then check (avoid races) */                          \
+     if ( unlikely(_shared->vcpu_data[0].evtchn_upcall_pending) )              \
+         force_evtchn_callback();                                              \
+ } while (0)
+ #define __save_flags(x)                                                       \
+ do {                                                                          \
+     (x) = HYPERVISOR_shared_info->vcpu_data[0].evtchn_upcall_mask;            \
+ } while (0)
+ #define __restore_flags(x)                                                    \
+ do {                                                                          \
+     shared_info_t *_shared = HYPERVISOR_shared_info;                          \
+     barrier();                                                                \
+     if ( (_shared->vcpu_data[0].evtchn_upcall_mask = x) == 0 ) {              \
+         barrier(); /* unmask then check (avoid races) */                      \
+         if ( unlikely(_shared->vcpu_data[0].evtchn_upcall_pending) )          \
+             force_evtchn_callback();                                          \
+     }                                                                         \
+ } while (0)
+ #define __save_and_cli(x)                                                     \
+ do {                                                                          \
+     (x) = HYPERVISOR_shared_info->vcpu_data[0].evtchn_upcall_mask;            \
+     HYPERVISOR_shared_info->vcpu_data[0].evtchn_upcall_mask = 1;              \
+     barrier();                                                                \
+ } while (0)
+ #define __save_and_sti(x)                                                     \
+ do {                                                                          \
+     shared_info_t *_shared = HYPERVISOR_shared_info;                          \
+     barrier();                                                                \
+     (x) = _shared->vcpu_data[0].evtchn_upcall_mask;                           \
+     _shared->vcpu_data[0].evtchn_upcall_mask = 0;                             \
+     barrier(); /* unmask then check (avoid races) */                          \
+     if ( unlikely(_shared->vcpu_data[0].evtchn_upcall_pending) )              \
+         force_evtchn_callback();                                              \
+ } while (0)
+ #define local_irq_save(x)       __save_and_cli(x)
+ #define local_irq_set(x)        __save_and_sti(x)
+ #define local_irq_restore(x)    __restore_flags(x)
+ #define local_irq_disable()     __cli()
+ #define local_irq_enable()      __sti()
+ #ifdef CONFIG_SMP
+ #error no SMP
+ extern void __global_cli(void);
+ extern void __global_sti(void);
+ extern unsigned long __global_save_flags(void);
+ extern void __global_restore_flags(unsigned long);
+ #define cli() __global_cli()
+ #define sti() __global_sti()
+ #define save_flags(x) ((x)=__global_save_flags())
+ #define restore_flags(x) __global_restore_flags(x)
+ #define save_and_cli(x) do { save_flags(x); cli(); } while(0);
+ #define save_and_sti(x) do { save_flags(x); sti(); } while(0);
+ #else
+ #define cli() __cli()
+ #define sti() __sti()
+ #define save_flags(x) __save_flags(x)
+ #define restore_flags(x) __restore_flags(x)
+ #define save_and_cli(x) __save_and_cli(x)
+ #define save_and_sti(x) __save_and_sti(x)
+ #endif
+ /*
+  * disable hlt during certain critical i/o operations
+  */
+ #define HAVE_DISABLE_HLT
+ void disable_hlt(void);
+ void enable_hlt(void);
+ extern unsigned long dmi_broken;
+ extern int is_sony_vaio_laptop;
+ #define BROKEN_ACPI_Sx                0x0001
+ #define BROKEN_INIT_AFTER_S1  0x0002
+ #define BROKEN_PNP_BIOS               0x0004
+ #endif
index 0000000000000000000000000000000000000000,7e8177802c3c1abb3686655031e5a4e54f89d19c..714d85e69f99ef03fc8682fdd18f3cf1a43452e2
mode 000000,100755..100755
--- /dev/null
@@@ -1,0 -1,283 +1,292 @@@
 -ln -sf ../../${LINUX_26}/include/asm-xen/multicall.h
+ #!/bin/bash
+ # mkbuildtree <build tree>
+ #
+ # Creates symbolic links in <build tree> for the sparse tree
+ # in the current directory.
+ # Script to determine the relative path between two directories.
+ # Copyright (c) D. J. Hawkey Jr. 2002
+ # Fixed for Xen project by K. Fraser in 2003.  
+ abs_to_rel ()
+ {
+       local CWD SRCPATH
+                 
+       if [ "$1" != "/" -a "${1##*[^/]}" = "/" ]; then
+               SRCPATH=${1%?}
+       else
+               SRCPATH=$1
+       fi
+       if [ "$2" != "/" -a "${2##*[^/]}" = "/" ]; then
+               DESTPATH=${2%?}
+       else
+               DESTPATH=$2
+       fi
+       CWD=$PWD
+       [ "${1%%[^/]*}" != "/" ] && cd $1 && SRCPATH=$PWD
+       [ "${2%%[^/]*}" != "/" ] && cd $2 && DESTPATH=$PWD
+       [ "$CWD" != "$PWD" ] && cd $CWD
+       BASEPATH=$SRCPATH
+       [ "$SRCPATH" = "$DESTPATH" ] && DESTPATH="." && return
+       [ "$SRCPATH" = "/" ] && DESTPATH=${DESTPATH#?} && return
+       while [ "$BASEPATH/" != "${DESTPATH%${DESTPATH#$BASEPATH/}}" ]; do
+           BASEPATH=${BASEPATH%/*}
+       done
+       SRCPATH=${SRCPATH#$BASEPATH}
+         DESTPATH=${DESTPATH#$BASEPATH}
+         DESTPATH=${DESTPATH#?}
+       while [ -n "$SRCPATH" ]; do
+               SRCPATH=${SRCPATH%/*}
+               DESTPATH="../$DESTPATH"
+       done
+       [ -z "$BASEPATH" ] && BASEPATH="/"
+       [ "${DESTPATH##*[^/]}" = "/" ] && DESTPATH=${DESTPATH%?}
+ }
+ # relative_lndir <target_dir>
+ # Creates a tree of symlinks in the current working directory that mirror
+ # real files in <target_dir>. <target_dir> should be relative to the current
+ # working directory. Symlinks in <target_dir> are ignored. Source-control files
+ # are ignored.
+ relative_lndir ()
+ {
+   local SYMLINK_DIR REAL_DIR pref i j
+   SYMLINK_DIR=$PWD
+   REAL_DIR=$1
+   (
+   cd $REAL_DIR
+   for i in `find . -type d | grep -v SCCS`; do
+     [ -d $SYMLINK_DIR/$i ] || mkdir -p $SYMLINK_DIR/$i
+     (
+     cd $i
+     pref=`echo $i | sed -e 's#/[^/]*#../#g' -e 's#^\.##'`
+     for j in `find . -maxdepth 1 -type f -o -type l`; do
+       ln -sf ${pref}${REAL_DIR}/$i/$j ${SYMLINK_DIR}/$i/$j
+     done
+     )
+   done
+   )
+ }
+ [ "$1" == "" ] && { echo "Syntax: $0 <linux tree to xenify>"; exit 1; }
+ # Get absolute path to the destination directory
+ pushd . >/dev/null
+ cd ${1} || { echo "cannot cd to ${1}"; exit 1; }
+ AD=$PWD
+ popd >/dev/null
+   
+ # Get absolute path to the source directory
+ AS=`pwd`
+ # Get path to source, relative to destination
+ abs_to_rel ${AD} ${AS}
+ RS=$DESTPATH
+ # Remove old copies of files and directories at the destination
+ for i in `find . -type f -o -type l` ; do rm -f ${AD}/${i#./} ; done
+ # We now work from the destination directory
+ cd ${AD} || { echo "cannot cd to ${AD}"; exit 1; }
+ # Remove old symlinks
+ for i in `find . -type l`; do rm -f $i; done
+ # Create symlinks of files and directories which exist in the sparse source
+ relative_lndir ${RS}
+ rm -f mkbuildtree
+ set ${RS}/../linux-2.6.*-xen-sparse
+ [ "$1" == "${RS}/../linux-2.6.*-xen-parse" ] && { echo "no Linux 2.6 sparse tree at ${RS}/../linux-2.6.*-xen-sparse"; exit 1; }
+ LINUX_26="$1"
+ # Create links to the shared definitions of the Xen interfaces.
+ rm -rf ${AD}/include/asm-xen/xen-public
+ mkdir  ${AD}/include/asm-xen/xen-public
+ cd     ${AD}/include/asm-xen/xen-public
+ relative_lndir ../../../${RS}/../xen/include/public
+ # Create a link to the shared definitions for the control interface
+ cd ${AD}/include/asm-xen
+ ## Symlinks for files:
+ ## - which are identical in the i386 and xen-i386 architecture-dependent
+ ##   subdirectories.
+ ## - which are identical in the Linux 2.6 and Linux 2.4 ports.
+ cd ${AD}/include/asm-xen
+ ln -sf ../asm-i386/a.out.h 
+ ln -sf ../asm-i386/apicdef.h 
+ ln -sf ../asm-i386/apic.h 
+ ln -sf ../asm-i386/atomic.h 
+ ln -sf ../asm-i386/bitops.h 
+ ln -sf ../asm-i386/boot.h 
+ ln -sf ../asm-i386/byteorder.h 
+ ln -sf ../asm-i386/cache.h 
+ ln -sf ../asm-i386/checksum.h 
+ ln -sf ../asm-i386/cpufeature.h 
+ ln -sf ../asm-i386/current.h 
+ ln -sf ../asm-i386/debugreg.h 
+ ln -sf ../asm-i386/delay.h 
+ ln -sf ../asm-i386/div64.h 
+ ln -sf ../asm-i386/dma.h 
+ ln -sf ../asm-i386/elf.h 
+ ln -sf ../asm-i386/errno.h 
+ ln -sf ../asm-i386/fcntl.h 
+ ln -sf ../asm-i386/floppy.h 
+ ln -sf ../asm-i386/hardirq.h 
+ ln -sf ../asm-i386/hdreg.h 
+ ln -sf ../asm-i386/i387.h 
+ ln -sf ../asm-i386/ide.h 
+ ln -sf ../asm-i386/init.h
+ ln -sf ../asm-i386/io_apic.h
+ ln -sf ../asm-i386/ioctl.h
+ ln -sf ../asm-i386/ioctls.h
+ ln -sf ../asm-i386/ipcbuf.h
+ ln -sf ../asm-i386/ipc.h
+ ln -sf ../asm-i386/kmap_types.h
+ ln -sf ../asm-i386/ldt.h 
+ ln -sf ../asm-i386/linux_logo.h
+ ln -sf ../asm-i386/locks.h 
+ ln -sf ../asm-i386/math_emu.h
+ ln -sf ../asm-i386/mc146818rtc.h
+ ln -sf ../asm-i386/mca_dma.h 
+ ln -sf ../asm-i386/mman.h 
+ ln -sf ../asm-i386/mmu.h 
+ ln -sf ../asm-i386/mmx.h 
+ ln -sf ../asm-i386/mpspec.h 
+ ln -sf ../asm-i386/msgbuf.h 
++ln -sf ../asm-i386/msr.h 
+ ln -sf ../asm-i386/mtrr.h 
+ ln -sf ../asm-i386/namei.h 
+ ln -sf ../asm-i386/param.h 
+ ln -sf ../asm-i386/parport.h 
+ ln -sf ../asm-i386/pgtable-3level.h 
+ ln -sf ../asm-i386/poll.h 
+ ln -sf ../asm-i386/posix_types.h 
+ ln -sf ../asm-i386/ptrace.h 
+ ln -sf ../asm-i386/resource.h 
+ ln -sf ../asm-i386/rwlock.h 
+ ln -sf ../asm-i386/rwsem.h 
+ ln -sf ../asm-i386/scatterlist.h
+ ln -sf ../asm-i386/semaphore.h 
+ ln -sf ../asm-i386/sembuf.h 
+ ln -sf ../asm-i386/serial.h 
+ ln -sf ../asm-i386/setup.h 
+ ln -sf ../asm-i386/shmbuf.h 
+ ln -sf ../asm-i386/shmparam.h 
+ ln -sf ../asm-i386/sigcontext.h 
+ ln -sf ../asm-i386/siginfo.h 
+ ln -sf ../asm-i386/signal.h 
+ ln -sf ../asm-i386/smplock.h 
+ ln -sf ../asm-i386/socket.h 
+ ln -sf ../asm-i386/sockios.h 
+ ln -sf ../asm-i386/softirq.h 
+ ln -sf ../asm-i386/spinlock.h 
+ ln -sf ../asm-i386/statfs.h 
+ ln -sf ../asm-i386/stat.h 
+ ln -sf ../asm-i386/string-486.h 
+ ln -sf ../asm-i386/string.h 
+ ln -sf ../asm-i386/termbits.h 
+ ln -sf ../asm-i386/termios.h 
+ ln -sf ../asm-i386/timex.h 
+ ln -sf ../asm-i386/tlb.h 
+ ln -sf ../asm-i386/types.h 
+ ln -sf ../asm-i386/uaccess.h 
+ ln -sf ../asm-i386/ucontext.h 
+ ln -sf ../asm-i386/unaligned.h
+ ln -sf ../asm-i386/unistd.h 
+ ln -sf ../asm-i386/user.h 
+ ln -sf ../asm-i386/vm86.h 
+ ln -sf ../../${LINUX_26}/include/asm-xen/balloon.h
+ ln -sf ../../${LINUX_26}/include/asm-xen/ctrl_if.h
+ ln -sf ../../${LINUX_26}/include/asm-xen/evtchn.h
++ln -sf ../../${LINUX_26}/include/asm-xen/gnttab.h
+ ln -sf ../../${LINUX_26}/include/asm-xen/hypervisor.h
 -ln -sf ../../../${LINUX_26}/arch/xen/i386/kernel/ioport.c
 -ln -sf ../../../${LINUX_26}/arch/xen/i386/kernel/pci-dma.c
+ ln -sf ../../${LINUX_26}/include/asm-xen/xen_proc.h
+ ln -sf ../../${LINUX_26}/include/asm-xen/asm-i386/synch_bitops.h
++ln -sf ../../${LINUX_26}/include/asm-xen/asm-i386/hypercall.h
+ mkdir -p linux-public && cd linux-public
+ ln -sf ../../../${LINUX_26}/include/asm-xen/linux-public/privcmd.h
+ ln -sf ../../../${LINUX_26}/include/asm-xen/linux-public/suspend.h
+ cd ${AD}/arch/xen/kernel
+ ln -sf ../../i386/kernel/i387.c
+ ln -sf ../../i386/kernel/init_task.c
+ ln -sf ../../i386/kernel/pci-i386.c
+ ln -sf ../../i386/kernel/pci-i386.h
+ ln -sf ../../i386/kernel/ptrace.c
+ ln -sf ../../i386/kernel/semaphore.c 
+ ln -sf ../../i386/kernel/sys_i386.c 
+ ln -sf ../../../${LINUX_26}/arch/xen/kernel/ctrl_if.c
+ ln -sf ../../../${LINUX_26}/arch/xen/kernel/evtchn.c
+ ln -sf ../../../${LINUX_26}/arch/xen/kernel/fixup.c
++ln -sf ../../../${LINUX_26}/arch/xen/kernel/gnttab.c
+ ln -sf ../../../${LINUX_26}/arch/xen/kernel/reboot.c
+ ln -sf ../../../${LINUX_26}/arch/xen/kernel/skbuff.c
+ cd ${AD}/arch/xen/lib
+ ln -sf ../../i386/lib/checksum.S 
+ ln -sf ../../i386/lib/dec_and_lock.c 
+ ln -sf ../../i386/lib/getuser.S 
+ ln -sf ../../i386/lib/iodebug.c 
+ ln -sf ../../i386/lib/memcpy.c 
+ ln -sf ../../i386/lib/mmx.c
+ ln -sf ../../i386/lib/old-checksum.c 
+ ln -sf ../../i386/lib/strstr.c 
+ ln -sf ../../i386/lib/usercopy.c 
+ ln -sf ../../../${LINUX_26}/arch/xen/kernel/xen_proc.c
+ cd ${AD}/arch/xen/mm
+ ln -sf ../../i386/mm/extable.c 
+ ln -sf ../../i386/mm/pageattr.c 
+ ln -sf ../../../${LINUX_26}/arch/xen/i386/mm/hypervisor.c
+ cd ${AD}/arch/xen/drivers/balloon
+ ln -sf ../../../../${LINUX_26}/drivers/xen/balloon/balloon.c
+ cd ${AD}/arch/xen/drivers/console
+ ln -sf ../../../../${LINUX_26}/drivers/xen/console/console.c 
+ cd ${AD}/arch/xen/drivers/dom0
+ ln -sf ../../../../${LINUX_26}/drivers/xen/privcmd/privcmd.c core.c
+ cd ${AD}/arch/xen/drivers/evtchn
+ ln -sf ../../../../${LINUX_26}/drivers/xen/evtchn/evtchn.c
+ cd ${AD}/arch/xen/drivers/netif/frontend
+ ln -sf ../../../../../${LINUX_26}/drivers/xen/netfront/netfront.c main.c
+ cd ${AD}/arch/xen/drivers/netif/backend
+ ln -sf ../../../../../${LINUX_26}/drivers/xen/netback/common.h
+ ln -sf ../../../../../${LINUX_26}/drivers/xen/netback/control.c
+ ln -sf ../../../../../${LINUX_26}/drivers/xen/netback/interface.c
+ ln -sf ../../../../../${LINUX_26}/drivers/xen/netback/netback.c main.c
+ cd ${AD}/arch/xen/drivers/blkif/backend
+ ln -sf ../../../../../${LINUX_26}/drivers/xen/blkback/common.h
+ ln -sf ../../../../../${LINUX_26}/drivers/xen/blkback/blkback.c main.c
+ ln -sf ../../../../../${LINUX_26}/drivers/xen/blkback/control.c
+ ln -sf ../../../../../${LINUX_26}/drivers/xen/blkback/interface.c
+ ln -sf ../../../../../${LINUX_26}/drivers/xen/blkback/vbd.c
+ cd ${AD}/arch/xen/drivers/blkif/frontend
+ ln -sf ../../../../../${LINUX_26}/drivers/xen/blkfront/blkfront.c
++cd ${AD}/arch/xen/drivers/usbif/frontend
++ln -sf ../../../../../${LINUX_26}/drivers/xen/usbfront/usbfront.c main.c
++ln -sf ../../../../../${LINUX_26}/drivers/xen/usbfront/xhci.h
++cd ${AD}/arch/xen/drivers/usbif/backend
++ln -sf ../../../../../${LINUX_26}/drivers/xen/usbback/common.h
++ln -sf ../../../../../${LINUX_26}/drivers/xen/usbback/control.c
++ln -sf ../../../../../${LINUX_26}/drivers/xen/usbback/interface.c
++ln -sf ../../../../../${LINUX_26}/drivers/xen/usbback/usbback.c main.c
index 0000000000000000000000000000000000000000,341e6e29a901def96cfcdd74cae1f7d5c591c64f..f8182820ac2241f7568415b62d0c7b3e85b04156
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,462 +1,461 @@@
 -      XEN_flush_page_update_queue();
+ /*
+  * High memory handling common code and variables.
+  *
+  * (C) 1999 Andrea Arcangeli, SuSE GmbH, andrea@suse.de
+  *          Gerhard Wichert, Siemens AG, Gerhard.Wichert@pdb.siemens.de
+  *
+  *
+  * Redesigned the x86 32-bit VM architecture to deal with
+  * 64-bit physical space. With current x86 CPUs this
+  * means up to 64 Gigabytes physical RAM.
+  *
+  * Rewrote high memory support to move the page cache into
+  * high memory. Implemented permanent (schedulable) kmaps
+  * based on Linus' idea.
+  *
+  * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
+  */
+ #include <linux/mm.h>
+ #include <linux/pagemap.h>
+ #include <linux/highmem.h>
+ #include <linux/swap.h>
+ #include <linux/slab.h>
+ /*
+  * Virtual_count is not a pure "count".
+  *  0 means that it is not mapped, and has not been mapped
+  *    since a TLB flush - it is usable.
+  *  1 means that there are no users, but it has been mapped
+  *    since the last TLB flush - so we can't use it.
+  *  n means that there are (n-1) current users of it.
+  */
+ static int pkmap_count[LAST_PKMAP];
+ static unsigned int last_pkmap_nr;
+ static spinlock_cacheline_t kmap_lock_cacheline = {SPIN_LOCK_UNLOCKED};
+ #define kmap_lock  kmap_lock_cacheline.lock
+ pte_t * pkmap_page_table;
+ static DECLARE_WAIT_QUEUE_HEAD(pkmap_map_wait);
+ static void flush_all_zero_pkmaps(void)
+ {
+       int i;
+       flush_cache_all();
+       for (i = 0; i < LAST_PKMAP; i++) {
+               struct page *page;
+               /*
+                * zero means we don't have anything to do,
+                * >1 means that it is still in use. Only
+                * a count of 1 means that it is free but
+                * needs to be unmapped
+                */
+               if (pkmap_count[i] != 1)
+                       continue;
+               pkmap_count[i] = 0;
+               /* sanity check */
+               if (pte_none(pkmap_page_table[i]))
+                       BUG();
+               /*
+                * Don't need an atomic fetch-and-clear op here;
+                * no-one has the page mapped, and cannot get at
+                * its virtual address (and hence PTE) without first
+                * getting the kmap_lock (which is held here).
+                * So no dangers, even with speculative execution.
+                */
+               page = pte_page(pkmap_page_table[i]);
+               pte_clear(&pkmap_page_table[i]);
+               page->virtual = NULL;
+       }
+       flush_tlb_all();
+ }
+ static inline unsigned long map_new_virtual(struct page *page, int nonblocking)
+ {
+       unsigned long vaddr;
+       int count;
+ start:
+       count = LAST_PKMAP;
+       /* Find an empty entry */
+       for (;;) {
+               last_pkmap_nr = (last_pkmap_nr + 1) & LAST_PKMAP_MASK;
+               if (!last_pkmap_nr) {
+                       flush_all_zero_pkmaps();
+                       count = LAST_PKMAP;
+               }
+               if (!pkmap_count[last_pkmap_nr])
+                       break;  /* Found a usable entry */
+               if (--count)
+                       continue;
+               if (nonblocking)
+                       return 0;
+               /*
+                * Sleep for somebody else to unmap their entries
+                */
+               {
+                       DECLARE_WAITQUEUE(wait, current);
+                       current->state = TASK_UNINTERRUPTIBLE;
+                       add_wait_queue(&pkmap_map_wait, &wait);
+                       spin_unlock(&kmap_lock);
+                       schedule();
+                       remove_wait_queue(&pkmap_map_wait, &wait);
+                       spin_lock(&kmap_lock);
+                       /* Somebody else might have mapped it while we slept */
+                       if (page->virtual)
+                               return (unsigned long) page->virtual;
+                       /* Re-start */
+                       goto start;
+               }
+       }
+       vaddr = PKMAP_ADDR(last_pkmap_nr);
+       set_pte(&(pkmap_page_table[last_pkmap_nr]), mk_pte(page, kmap_prot));
+       pkmap_count[last_pkmap_nr] = 1;
+       page->virtual = (void *) vaddr;
+       return vaddr;
+ }
+ void kmap_flush_unused(void)
+ {
+       spin_lock(&kmap_lock);
+       flush_all_zero_pkmaps();
+       spin_unlock(&kmap_lock);
+ }
+ void fastcall *kmap_high(struct page *page, int nonblocking)
+ {
+       unsigned long vaddr;
+       /*
+        * For highmem pages, we can't trust "virtual" until
+        * after we have the lock.
+        *
+        * We cannot call this from interrupts, as it may block
+        */
+       spin_lock(&kmap_lock);
+       vaddr = (unsigned long) page->virtual;
+       if (!vaddr) {
+               vaddr = map_new_virtual(page, nonblocking);
+               if (!vaddr)
+                       goto out;
+       }
+       pkmap_count[PKMAP_NR(vaddr)]++;
+       if (pkmap_count[PKMAP_NR(vaddr)] < 2)
+               BUG();
+  out:
+       spin_unlock(&kmap_lock);
+       return (void*) vaddr;
+ }
+ void fastcall kunmap_high(struct page *page)
+ {
+       unsigned long vaddr;
+       unsigned long nr;
+       int need_wakeup;
+       spin_lock(&kmap_lock);
+       vaddr = (unsigned long) page->virtual;
+       if (!vaddr)
+               BUG();
+       nr = PKMAP_NR(vaddr);
+       /*
+        * A count must never go down to zero
+        * without a TLB flush!
+        */
+       need_wakeup = 0;
+       switch (--pkmap_count[nr]) {
+       case 0:
+               BUG();
+       case 1:
+               /*
+                * Avoid an unnecessary wake_up() function call.
+                * The common case is pkmap_count[] == 1, but
+                * no waiters.
+                * The tasks queued in the wait-queue are guarded
+                * by both the lock in the wait-queue-head and by
+                * the kmap_lock.  As the kmap_lock is held here,
+                * no need for the wait-queue-head's lock.  Simply
+                * test if the queue is empty.
+                */
+               need_wakeup = waitqueue_active(&pkmap_map_wait);
+       }
+       spin_unlock(&kmap_lock);
+       /* do wake-up, if needed, race-free outside of the spin lock */
+       if (need_wakeup)
+               wake_up(&pkmap_map_wait);
+ }
+ #define POOL_SIZE 32
+ /*
+  * This lock gets no contention at all, normally.
+  */
+ static spinlock_t emergency_lock = SPIN_LOCK_UNLOCKED;
+ int nr_emergency_pages;
+ static LIST_HEAD(emergency_pages);
+ int nr_emergency_bhs;
+ static LIST_HEAD(emergency_bhs);
+ /*
+  * Simple bounce buffer support for highmem pages.
+  * This will be moved to the block layer in 2.5.
+  */
+ static inline void copy_from_high_bh (struct buffer_head *to,
+                        struct buffer_head *from)
+ {
+       struct page *p_from;
+       char *vfrom;
+       p_from = from->b_page;
+       vfrom = kmap_atomic(p_from, KM_USER0);
+       memcpy(to->b_data, vfrom + bh_offset(from), to->b_size);
+       kunmap_atomic(vfrom, KM_USER0);
+ }
+ static inline void copy_to_high_bh_irq (struct buffer_head *to,
+                        struct buffer_head *from)
+ {
+       struct page *p_to;
+       char *vto;
+       unsigned long flags;
+       p_to = to->b_page;
+       __save_flags(flags);
+       __cli();
+       vto = kmap_atomic(p_to, KM_BOUNCE_READ);
+       memcpy(vto + bh_offset(to), from->b_data, to->b_size);
+       kunmap_atomic(vto, KM_BOUNCE_READ);
+       __restore_flags(flags);
+ }
+ static inline void bounce_end_io (struct buffer_head *bh, int uptodate)
+ {
+       struct page *page;
+       struct buffer_head *bh_orig = (struct buffer_head *)(bh->b_private);
+       unsigned long flags;
+       bh_orig->b_end_io(bh_orig, uptodate);
+       page = bh->b_page;
+       spin_lock_irqsave(&emergency_lock, flags);
+       if (nr_emergency_pages >= POOL_SIZE)
+               __free_page(page);
+       else {
+               /*
+                * We are abusing page->list to manage
+                * the highmem emergency pool:
+                */
+               list_add(&page->list, &emergency_pages);
+               nr_emergency_pages++;
+       }
+       
+       if (nr_emergency_bhs >= POOL_SIZE) {
+ #ifdef HIGHMEM_DEBUG
+               /* Don't clobber the constructed slab cache */
+               init_waitqueue_head(&bh->b_wait);
+ #endif
+               kmem_cache_free(bh_cachep, bh);
+       } else {
+               /*
+                * Ditto in the bh case, here we abuse b_inode_buffers:
+                */
+               list_add(&bh->b_inode_buffers, &emergency_bhs);
+               nr_emergency_bhs++;
+       }
+       spin_unlock_irqrestore(&emergency_lock, flags);
+ }
+ static __init int init_emergency_pool(void)
+ {
+       struct sysinfo i;
+         si_meminfo(&i);
+         si_swapinfo(&i);
+         
+         if (!i.totalhigh)
+               return 0;
+       spin_lock_irq(&emergency_lock);
+       while (nr_emergency_pages < POOL_SIZE) {
+               struct page * page = alloc_page(GFP_ATOMIC);
+               if (!page) {
+                       printk("couldn't refill highmem emergency pages");
+                       break;
+               }
+               list_add(&page->list, &emergency_pages);
+               nr_emergency_pages++;
+       }
+       while (nr_emergency_bhs < POOL_SIZE) {
+               struct buffer_head * bh = kmem_cache_alloc(bh_cachep, SLAB_ATOMIC);
+               if (!bh) {
+                       printk("couldn't refill highmem emergency bhs");
+                       break;
+               }
+               list_add(&bh->b_inode_buffers, &emergency_bhs);
+               nr_emergency_bhs++;
+       }
+       spin_unlock_irq(&emergency_lock);
+       printk("allocated %d pages and %d bhs reserved for the highmem bounces\n",
+              nr_emergency_pages, nr_emergency_bhs);
+       return 0;
+ }
+ __initcall(init_emergency_pool);
+ static void bounce_end_io_write (struct buffer_head *bh, int uptodate)
+ {
+       bounce_end_io(bh, uptodate);
+ }
+ static void bounce_end_io_read (struct buffer_head *bh, int uptodate)
+ {
+       struct buffer_head *bh_orig = (struct buffer_head *)(bh->b_private);
+       if (uptodate)
+               copy_to_high_bh_irq(bh_orig, bh);
+       bounce_end_io(bh, uptodate);
+ }
+ struct page *alloc_bounce_page (void)
+ {
+       struct list_head *tmp;
+       struct page *page;
+       page = alloc_page(GFP_NOHIGHIO);
+       if (page)
+               return page;
+       /*
+        * No luck. First, kick the VM so it doesn't idle around while
+        * we are using up our emergency rations.
+        */
+       wakeup_bdflush();
+ repeat_alloc:
+       /*
+        * Try to allocate from the emergency pool.
+        */
+       tmp = &emergency_pages;
+       spin_lock_irq(&emergency_lock);
+       if (!list_empty(tmp)) {
+               page = list_entry(tmp->next, struct page, list);
+               list_del(tmp->next);
+               nr_emergency_pages--;
+       }
+       spin_unlock_irq(&emergency_lock);
+       if (page)
+               return page;
+       /* we need to wait I/O completion */
+       run_task_queue(&tq_disk);
+       yield();
+       goto repeat_alloc;
+ }
+ struct buffer_head *alloc_bounce_bh (void)
+ {
+       struct list_head *tmp;
+       struct buffer_head *bh;
+       bh = kmem_cache_alloc(bh_cachep, SLAB_NOHIGHIO);
+       if (bh)
+               return bh;
+       /*
+        * No luck. First, kick the VM so it doesn't idle around while
+        * we are using up our emergency rations.
+        */
+       wakeup_bdflush();
+ repeat_alloc:
+       /*
+        * Try to allocate from the emergency pool.
+        */
+       tmp = &emergency_bhs;
+       spin_lock_irq(&emergency_lock);
+       if (!list_empty(tmp)) {
+               bh = list_entry(tmp->next, struct buffer_head, b_inode_buffers);
+               list_del(tmp->next);
+               nr_emergency_bhs--;
+       }
+       spin_unlock_irq(&emergency_lock);
+       if (bh)
+               return bh;
+       /* we need to wait I/O completion */
+       run_task_queue(&tq_disk);
+       yield();
+       goto repeat_alloc;
+ }
+ struct buffer_head * create_bounce(int rw, struct buffer_head * bh_orig)
+ {
+       struct page *page;
+       struct buffer_head *bh;
+       if (!PageHighMem(bh_orig->b_page))
+               return bh_orig;
+       bh = alloc_bounce_bh();
+       /*
+        * This is wasteful for 1k buffers, but this is a stopgap measure
+        * and we are being ineffective anyway. This approach simplifies
+        * things immensly. On boxes with more than 4GB RAM this should
+        * not be an issue anyway.
+        */
+       page = alloc_bounce_page();
+       set_bh_page(bh, page, 0);
+       bh->b_next = NULL;
+       bh->b_blocknr = bh_orig->b_blocknr;
+       bh->b_size = bh_orig->b_size;
+       bh->b_list = -1;
+       bh->b_dev = bh_orig->b_dev;
+       bh->b_count = bh_orig->b_count;
+       bh->b_rdev = bh_orig->b_rdev;
+       bh->b_state = bh_orig->b_state;
+ #ifdef HIGHMEM_DEBUG
+       bh->b_flushtime = jiffies;
+       bh->b_next_free = NULL;
+       bh->b_prev_free = NULL;
+       /* bh->b_this_page */
+       bh->b_reqnext = NULL;
+       bh->b_pprev = NULL;
+ #endif
+       /* bh->b_page */
+       if (rw == WRITE) {
+               bh->b_end_io = bounce_end_io_write;
+               copy_from_high_bh(bh, bh_orig);
+       } else
+               bh->b_end_io = bounce_end_io_read;
+       bh->b_private = (void *)bh_orig;
+       bh->b_rsector = bh_orig->b_rsector;
+ #ifdef HIGHMEM_DEBUG
+       memset(&bh->b_wait, -1, sizeof(bh->b_wait));
+ #endif
+       return bh;
+ }
index 0000000000000000000000000000000000000000,8f61e6657a1cbef1b1d21371e62f62779fe7d219..6b7c807fd3d0d4c01ffba3b1361106cba1d376ed
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,1548 +1,1534 @@@
 -      XEN_flush_page_update_queue();
+ /*
+  *  linux/mm/memory.c
+  *
+  *  Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
+  */
+ /*
+  * demand-loading started 01.12.91 - seems it is high on the list of
+  * things wanted, and it should be easy to implement. - Linus
+  */
+ /*
+  * Ok, demand-loading was easy, shared pages a little bit tricker. Shared
+  * pages started 02.12.91, seems to work. - Linus.
+  *
+  * Tested sharing by executing about 30 /bin/sh: under the old kernel it
+  * would have taken more than the 6M I have free, but it worked well as
+  * far as I could see.
+  *
+  * Also corrected some "invalidate()"s - I wasn't doing enough of them.
+  */
+ /*
+  * Real VM (paging to/from disk) started 18.12.91. Much more work and
+  * thought has to go into this. Oh, well..
+  * 19.12.91  -  works, somewhat. Sometimes I get faults, don't know why.
+  *            Found it. Everything seems to work now.
+  * 20.12.91  -  Ok, making the swap-device changeable like the root.
+  */
+ /*
+  * 05.04.94  -  Multi-page memory management added for v1.1.
+  *            Idea by Alex Bligh (alex@cconcepts.co.uk)
+  *
+  * 16.07.99  -  Support of BIGMEM added by Gerhard Wichert, Siemens AG
+  *            (Gerhard.Wichert@pdb.siemens.de)
+  */
+ #include <linux/mm.h>
+ #include <linux/mman.h>
+ #include <linux/swap.h>
+ #include <linux/smp_lock.h>
+ #include <linux/swapctl.h>
+ #include <linux/iobuf.h>
+ #include <linux/highmem.h>
+ #include <linux/pagemap.h>
+ #include <linux/module.h>
+ #include <asm/pgalloc.h>
+ #include <asm/uaccess.h>
+ #include <asm/tlb.h>
+ unsigned long max_mapnr;
+ unsigned long num_physpages;
+ unsigned long num_mappedpages;
+ void * high_memory;
+ struct page *highmem_start_page;
+ /*
+  * We special-case the C-O-W ZERO_PAGE, because it's such
+  * a common occurrence (no need to read the page to know
+  * that it's zero - better for the cache and memory subsystem).
+  */
+ static inline void copy_cow_page(struct page * from, struct page * to, unsigned long address)
+ {
+       if (from == ZERO_PAGE(address)) {
+               clear_user_highpage(to, address);
+               return;
+       }
+       copy_user_highpage(to, from, address);
+ }
+ mem_map_t * mem_map;
+ /*
+  * Called by TLB shootdown 
+  */
+ void __free_pte(pte_t pte)
+ {
+       struct page *page = pte_page(pte);
+       if ((!VALID_PAGE(page)) || PageReserved(page))
+               return;
+       if (pte_dirty(pte))
+               set_page_dirty(page);           
+       free_page_and_swap_cache(page);
+ }
+ /*
+  * Note: this doesn't free the actual pages themselves. That
+  * has been handled earlier when unmapping all the memory regions.
+  */
+ static inline void free_one_pmd(pmd_t * dir)
+ {
+       pte_t * pte;
+       if (pmd_none(*dir))
+               return;
+       if (pmd_bad(*dir)) {
+               pmd_ERROR(*dir);
+               pmd_clear(dir);
+               return;
+       }
+       pte = pte_offset(dir, 0);
+       pmd_clear(dir);
+       pte_free(pte);
+ }
+ static inline void free_one_pgd(pgd_t * dir)
+ {
+       int j;
+       pmd_t * pmd;
+       if (pgd_none(*dir))
+               return;
+       if (pgd_bad(*dir)) {
+               pgd_ERROR(*dir);
+               pgd_clear(dir);
+               return;
+       }
+       pmd = pmd_offset(dir, 0);
+       pgd_clear(dir);
+       for (j = 0; j < PTRS_PER_PMD ; j++) {
+               prefetchw(pmd+j+(PREFETCH_STRIDE/16));
+               free_one_pmd(pmd+j);
+       }
+       pmd_free(pmd);
+ }
+ /* Low and high watermarks for page table cache.
+    The system should try to have pgt_water[0] <= cache elements <= pgt_water[1]
+  */
+ int pgt_cache_water[2] = { 25, 50 };
+ /* Returns the number of pages freed */
+ int check_pgt_cache(void)
+ {
+       return do_check_pgt_cache(pgt_cache_water[0], pgt_cache_water[1]);
+ }
+ /*
+  * This function clears all user-level page tables of a process - this
+  * is needed by execve(), so that old pages aren't in the way.
+  */
+ void clear_page_tables(struct mm_struct *mm, unsigned long first, int nr)
+ {
+       pgd_t * page_dir = mm->pgd;
+       spin_lock(&mm->page_table_lock);
+       page_dir += first;
+       do {
+               free_one_pgd(page_dir);
+               page_dir++;
+       } while (--nr);
 -                                      /* XEN modification: modified ordering here to avoid RaW hazard. */
 -                                      pte = *src_pte;
 -                                      pte = pte_wrprotect(pte);
+       spin_unlock(&mm->page_table_lock);
+       /* keep the page table cache within bounds */
+       check_pgt_cache();
+ }
+ #define PTE_TABLE_MASK        ((PTRS_PER_PTE-1) * sizeof(pte_t))
+ #define PMD_TABLE_MASK        ((PTRS_PER_PMD-1) * sizeof(pmd_t))
+ /*
+  * copy one vm_area from one task to the other. Assumes the page tables
+  * already present in the new task to be cleared in the whole range
+  * covered by this vma.
+  *
+  * 08Jan98 Merged into one routine from several inline routines to reduce
+  *         variable count and make things faster. -jj
+  *
+  * dst->page_table_lock is held on entry and exit,
+  * but may be dropped within pmd_alloc() and pte_alloc().
+  */
+ int copy_page_range(struct mm_struct *dst, struct mm_struct *src,
+                       struct vm_area_struct *vma)
+ {
+       pgd_t * src_pgd, * dst_pgd;
+       unsigned long address = vma->vm_start;
+       unsigned long end = vma->vm_end;
+       unsigned long cow = (vma->vm_flags & (VM_SHARED | VM_MAYWRITE)) == VM_MAYWRITE;
+       src_pgd = pgd_offset(src, address)-1;
+       dst_pgd = pgd_offset(dst, address)-1;
+       for (;;) {
+               pmd_t * src_pmd, * dst_pmd;
+               src_pgd++; dst_pgd++;
+               
+               /* copy_pmd_range */
+               
+               if (pgd_none(*src_pgd))
+                       goto skip_copy_pmd_range;
+               if (pgd_bad(*src_pgd)) {
+                       pgd_ERROR(*src_pgd);
+                       pgd_clear(src_pgd);
+ skip_copy_pmd_range:  address = (address + PGDIR_SIZE) & PGDIR_MASK;
+                       if (!address || (address >= end))
+                               goto out;
+                       continue;
+               }
+               src_pmd = pmd_offset(src_pgd, address);
+               dst_pmd = pmd_alloc(dst, dst_pgd, address);
+               if (!dst_pmd)
+                       goto nomem;
+               do {
+                       pte_t * src_pte, * dst_pte;
+               
+                       /* copy_pte_range */
+               
+                       if (pmd_none(*src_pmd))
+                               goto skip_copy_pte_range;
+                       if (pmd_bad(*src_pmd)) {
+                               pmd_ERROR(*src_pmd);
+                               pmd_clear(src_pmd);
+ skip_copy_pte_range:          address = (address + PMD_SIZE) & PMD_MASK;
+                               if (address >= end)
+                                       goto out;
+                               goto cont_copy_pmd_range;
+                       }
+                       src_pte = pte_offset(src_pmd, address);
+                       dst_pte = pte_alloc(dst, dst_pmd, address);
+                       if (!dst_pte)
+                               goto nomem;
+                       spin_lock(&src->page_table_lock);                       
+                       do {
+                               pte_t pte = *src_pte;
+                               struct page *ptepage;
+                               
+                               /* copy_one_pte */
+                               if (pte_none(pte))
+                                       goto cont_copy_pte_range_noset;
+                               if (!pte_present(pte)) {
+                                       swap_duplicate(pte_to_swp_entry(pte));
+                                       goto cont_copy_pte_range;
+                               }
+                               ptepage = pte_page(pte);
+                               if ((!VALID_PAGE(ptepage)) || 
+                                   PageReserved(ptepage))
+                                       goto cont_copy_pte_range;
+                               /* If it's a COW mapping, write protect it both in the parent and the child */
+                               if (cow && pte_write(pte)) {
 -              XEN_flush_page_update_queue();
 -              HYPERVISOR_update_va_mapping(address>>PAGE_SHIFT, entry, UVMF_INVLPG);
+                                       ptep_set_wrprotect(src_pte);
++                                      pte = *src_pte;
+                               }
+                               /* If it's a shared mapping, mark it clean in the child */
+                               if (vma->vm_flags & VM_SHARED)
+                                       pte = pte_mkclean(pte);
+                               pte = pte_mkold(pte);
+                               get_page(ptepage);
+                               dst->rss++;
+ cont_copy_pte_range:          set_pte(dst_pte, pte);
+ cont_copy_pte_range_noset:    address += PAGE_SIZE;
+                               if (address >= end)
+                                       goto out_unlock;
+                               src_pte++;
+                               dst_pte++;
+                       } while ((unsigned long)src_pte & PTE_TABLE_MASK);
+                       spin_unlock(&src->page_table_lock);
+               
+ cont_copy_pmd_range:  src_pmd++;
+                       dst_pmd++;
+               } while ((unsigned long)src_pmd & PMD_TABLE_MASK);
+       }
+ out_unlock:
+       spin_unlock(&src->page_table_lock);
+ out:
+       return 0;
+ nomem:
+       return -ENOMEM;
+ }
+ /*
+  * Return indicates whether a page was freed so caller can adjust rss
+  */
+ static inline void forget_pte(pte_t page)
+ {
+       if (!pte_none(page)) {
+               printk("forget_pte: old mapping existed!\n");
+               BUG();
+       }
+ }
+ static inline int zap_pte_range(mmu_gather_t *tlb, pmd_t * pmd, unsigned long address, unsigned long size)
+ {
+       unsigned long offset;
+       pte_t * ptep;
+       int freed = 0;
+       if (pmd_none(*pmd))
+               return 0;
+       if (pmd_bad(*pmd)) {
+               pmd_ERROR(*pmd);
+               pmd_clear(pmd);
+               return 0;
+       }
+       ptep = pte_offset(pmd, address);
+       offset = address & ~PMD_MASK;
+       if (offset + size > PMD_SIZE)
+               size = PMD_SIZE - offset;
+       size &= PAGE_MASK;
+       for (offset=0; offset < size; ptep++, offset += PAGE_SIZE) {
+               pte_t pte = *ptep;
+               if (pte_none(pte))
+                       continue;
+               if (pte_present(pte)) {
+                       struct page *page = pte_page(pte);
+                       if (VALID_PAGE(page) && !PageReserved(page))
+                               freed ++;
+                       /* This will eventually call __free_pte on the pte. */
+                       tlb_remove_page(tlb, ptep, address + offset);
+               } else {
+                       free_swap_and_cache(pte_to_swp_entry(pte));
+                       pte_clear(ptep);
+               }
+       }
+       return freed;
+ }
+ static inline int zap_pmd_range(mmu_gather_t *tlb, pgd_t * dir, unsigned long address, unsigned long size)
+ {
+       pmd_t * pmd;
+       unsigned long end;
+       int freed;
+       if (pgd_none(*dir))
+               return 0;
+       if (pgd_bad(*dir)) {
+               pgd_ERROR(*dir);
+               pgd_clear(dir);
+               return 0;
+       }
+       pmd = pmd_offset(dir, address);
+       end = address + size;
+       if (end > ((address + PGDIR_SIZE) & PGDIR_MASK))
+               end = ((address + PGDIR_SIZE) & PGDIR_MASK);
+       freed = 0;
+       do {
+               freed += zap_pte_range(tlb, pmd, address, end - address);
+               address = (address + PMD_SIZE) & PMD_MASK; 
+               pmd++;
+       } while (address < end);
+       return freed;
+ }
+ /*
+  * remove user pages in a given range.
+  */
+ void zap_page_range(struct mm_struct *mm, unsigned long address, unsigned long size)
+ {
+       mmu_gather_t *tlb;
+       pgd_t * dir;
+       unsigned long start = address, end = address + size;
+       int freed = 0;
+       dir = pgd_offset(mm, address);
+       /*
+        * This is a long-lived spinlock. That's fine.
+        * There's no contention, because the page table
+        * lock only protects against kswapd anyway, and
+        * even if kswapd happened to be looking at this
+        * process we _want_ it to get stuck.
+        */
+       if (address >= end)
+               BUG();
+       spin_lock(&mm->page_table_lock);
+       flush_cache_range(mm, address, end);
+       tlb = tlb_gather_mmu(mm);
+       do {
+               freed += zap_pmd_range(tlb, dir, address, end - address);
+               address = (address + PGDIR_SIZE) & PGDIR_MASK;
+               dir++;
+       } while (address && (address < end));
+       /* this will flush any remaining tlb entries */
+       tlb_finish_mmu(tlb, start, end);
+       /*
+        * Update rss for the mm_struct (not necessarily current->mm)
+        * Notice that rss is an unsigned long.
+        */
+       if (mm->rss > freed)
+               mm->rss -= freed;
+       else
+               mm->rss = 0;
+       spin_unlock(&mm->page_table_lock);
+ }
+ /*
+  * Do a quick page-table lookup for a single page. 
+  */
+ static struct page * follow_page(struct mm_struct *mm, unsigned long address, int write) 
+ {
+       pgd_t *pgd;
+       pmd_t *pmd;
+       pte_t *ptep, pte;
+       pgd = pgd_offset(mm, address);
+       if (pgd_none(*pgd) || pgd_bad(*pgd))
+               goto out;
+       pmd = pmd_offset(pgd, address);
+       if (pmd_none(*pmd) || pmd_bad(*pmd))
+               goto out;
+       ptep = pte_offset(pmd, address);
+       if (!ptep)
+               goto out;
+       pte = *ptep;
+       if (pte_present(pte)) {
+               if (!write ||
+                   (pte_write(pte) && pte_dirty(pte)))
+                       return pte_page(pte);
+       }
+ out:
+       return 0;
+ }
+ /* 
+  * Given a physical address, is there a useful struct page pointing to
+  * it?  This may become more complex in the future if we start dealing
+  * with IO-aperture pages in kiobufs.
+  */
+ static inline struct page * get_page_map(struct page *page)
+ {
+       if (!VALID_PAGE(page))
+               return 0;
+       return page;
+ }
+ /*
+  * Please read Documentation/cachetlb.txt before using this function,
+  * accessing foreign memory spaces can cause cache coherency problems.
+  *
+  * Accessing a VM_IO area is even more dangerous, therefore the function
+  * fails if pages is != NULL and a VM_IO area is found.
+  */
+ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start,
+               int len, int write, int force, struct page **pages, struct vm_area_struct **vmas)
+ {
+       int i;
+       unsigned int flags;
+       /*
+        * Require read or write permissions.
+        * If 'force' is set, we only require the "MAY" flags.
+        */
+       flags = write ? (VM_WRITE | VM_MAYWRITE) : (VM_READ | VM_MAYREAD);
+       flags &= force ? (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
+       i = 0;
+       do {
+               struct vm_area_struct * vma;
+               vma = find_extend_vma(mm, start);
+               if ( !vma || (pages && vma->vm_flags & VM_IO) || !(flags & vma->vm_flags) )
+                       return i ? : -EFAULT;
+               spin_lock(&mm->page_table_lock);
+               do {
+                       struct page *map;
+                       while (!(map = follow_page(mm, start, write))) {
+                               spin_unlock(&mm->page_table_lock);
+                               switch (handle_mm_fault(mm, vma, start, write)) {
+                               case 1:
+                                       tsk->min_flt++;
+                                       break;
+                               case 2:
+                                       tsk->maj_flt++;
+                                       break;
+                               case 0:
+                                       if (i) return i;
+                                       return -EFAULT;
+                               default:
+                                       if (i) return i;
+                                       return -ENOMEM;
+                               }
+                               spin_lock(&mm->page_table_lock);
+                       }
+                       if (pages) {
+                               pages[i] = get_page_map(map);
+                               /* FIXME: call the correct function,
+                                * depending on the type of the found page
+                                */
+                               if (!pages[i] || PageReserved(pages[i])) {
+                                       if (pages[i] != ZERO_PAGE(start))
+                                               goto bad_page;
+                               } else
+                                       page_cache_get(pages[i]);
+                       }
+                       if (vmas)
+                               vmas[i] = vma;
+                       i++;
+                       start += PAGE_SIZE;
+                       len--;
+               } while(len && start < vma->vm_end);
+               spin_unlock(&mm->page_table_lock);
+       } while(len);
+ out:
+       return i;
+       /*
+        * We found an invalid page in the VMA.  Release all we have
+        * so far and fail.
+        */
+ bad_page:
+       spin_unlock(&mm->page_table_lock);
+       while (i--)
+               page_cache_release(pages[i]);
+       i = -EFAULT;
+       goto out;
+ }
+ EXPORT_SYMBOL(get_user_pages);
+ /*
+  * Force in an entire range of pages from the current process's user VA,
+  * and pin them in physical memory.  
+  */
+ #define dprintk(x...)
+ int map_user_kiobuf(int rw, struct kiobuf *iobuf, unsigned long va, size_t len)
+ {
+       int pgcount, err;
+       struct mm_struct *      mm;
+       
+       /* Make sure the iobuf is not already mapped somewhere. */
+       if (iobuf->nr_pages)
+               return -EINVAL;
+       mm = current->mm;
+       dprintk ("map_user_kiobuf: begin\n");
+       
+       pgcount = (va + len + PAGE_SIZE - 1)/PAGE_SIZE - va/PAGE_SIZE;
+       /* mapping 0 bytes is not permitted */
+       if (!pgcount) BUG();
+       err = expand_kiobuf(iobuf, pgcount);
+       if (err)
+               return err;
+       iobuf->locked = 0;
+       iobuf->offset = va & (PAGE_SIZE-1);
+       iobuf->length = len;
+       
+       /* Try to fault in all of the necessary pages */
+       down_read(&mm->mmap_sem);
+       /* rw==READ means read from disk, write into memory area */
+       err = get_user_pages(current, mm, va, pgcount,
+                       (rw==READ), 0, iobuf->maplist, NULL);
+       up_read(&mm->mmap_sem);
+       if (err < 0) {
+               unmap_kiobuf(iobuf);
+               dprintk ("map_user_kiobuf: end %d\n", err);
+               return err;
+       }
+       iobuf->nr_pages = err;
+       while (pgcount--) {
+               /* FIXME: flush superflous for rw==READ,
+                * probably wrong function for rw==WRITE
+                */
+               flush_dcache_page(iobuf->maplist[pgcount]);
+       }
+       dprintk ("map_user_kiobuf: end OK\n");
+       return 0;
+ }
+ /*
+  * Mark all of the pages in a kiobuf as dirty 
+  *
+  * We need to be able to deal with short reads from disk: if an IO error
+  * occurs, the number of bytes read into memory may be less than the
+  * size of the kiobuf, so we have to stop marking pages dirty once the
+  * requested byte count has been reached.
+  *
+  * Must be called from process context - set_page_dirty() takes VFS locks.
+  */
+ void mark_dirty_kiobuf(struct kiobuf *iobuf, int bytes)
+ {
+       int index, offset, remaining;
+       struct page *page;
+       
+       index = iobuf->offset >> PAGE_SHIFT;
+       offset = iobuf->offset & ~PAGE_MASK;
+       remaining = bytes;
+       if (remaining > iobuf->length)
+               remaining = iobuf->length;
+       
+       while (remaining > 0 && index < iobuf->nr_pages) {
+               page = iobuf->maplist[index];
+               
+               if (!PageReserved(page))
+                       set_page_dirty(page);
+               remaining -= (PAGE_SIZE - offset);
+               offset = 0;
+               index++;
+       }
+ }
+ /*
+  * Unmap all of the pages referenced by a kiobuf.  We release the pages,
+  * and unlock them if they were locked. 
+  */
+ void unmap_kiobuf (struct kiobuf *iobuf) 
+ {
+       int i;
+       struct page *map;
+       
+       for (i = 0; i < iobuf->nr_pages; i++) {
+               map = iobuf->maplist[i];
+               if (map) {
+                       if (iobuf->locked)
+                               UnlockPage(map);
+                       /* FIXME: cache flush missing for rw==READ
+                        * FIXME: call the correct reference counting function
+                        */
+                       page_cache_release(map);
+               }
+       }
+       
+       iobuf->nr_pages = 0;
+       iobuf->locked = 0;
+ }
+ /*
+  * Lock down all of the pages of a kiovec for IO.
+  *
+  * If any page is mapped twice in the kiovec, we return the error -EINVAL.
+  *
+  * The optional wait parameter causes the lock call to block until all
+  * pages can be locked if set.  If wait==0, the lock operation is
+  * aborted if any locked pages are found and -EAGAIN is returned.
+  */
+ int lock_kiovec(int nr, struct kiobuf *iovec[], int wait)
+ {
+       struct kiobuf *iobuf;
+       int i, j;
+       struct page *page, **ppage;
+       int doublepage = 0;
+       int repeat = 0;
+       
+  repeat:
+       
+       for (i = 0; i < nr; i++) {
+               iobuf = iovec[i];
+               if (iobuf->locked)
+                       continue;
+               ppage = iobuf->maplist;
+               for (j = 0; j < iobuf->nr_pages; ppage++, j++) {
+                       page = *ppage;
+                       if (!page)
+                               continue;
+                       
+                       if (TryLockPage(page)) {
+                               while (j--) {
+                                       struct page *tmp = *--ppage;
+                                       if (tmp)
+                                               UnlockPage(tmp);
+                               }
+                               goto retry;
+                       }
+               }
+               iobuf->locked = 1;
+       }
+       return 0;
+       
+  retry:
+       
+       /* 
+        * We couldn't lock one of the pages.  Undo the locking so far,
+        * wait on the page we got to, and try again.  
+        */
+       
+       unlock_kiovec(nr, iovec);
+       if (!wait)
+               return -EAGAIN;
+       
+       /* 
+        * Did the release also unlock the page we got stuck on?
+        */
+       if (!PageLocked(page)) {
+               /* 
+                * If so, we may well have the page mapped twice
+                * in the IO address range.  Bad news.  Of
+                * course, it _might_ just be a coincidence,
+                * but if it happens more than once, chances
+                * are we have a double-mapped page. 
+                */
+               if (++doublepage >= 3) 
+                       return -EINVAL;
+               
+               /* Try again...  */
+               wait_on_page(page);
+       }
+       
+       if (++repeat < 16)
+               goto repeat;
+       return -EAGAIN;
+ }
+ /*
+  * Unlock all of the pages of a kiovec after IO.
+  */
+ int unlock_kiovec(int nr, struct kiobuf *iovec[])
+ {
+       struct kiobuf *iobuf;
+       int i, j;
+       struct page *page, **ppage;
+       
+       for (i = 0; i < nr; i++) {
+               iobuf = iovec[i];
+               if (!iobuf->locked)
+                       continue;
+               iobuf->locked = 0;
+               
+               ppage = iobuf->maplist;
+               for (j = 0; j < iobuf->nr_pages; ppage++, j++) {
+                       page = *ppage;
+                       if (!page)
+                               continue;
+                       UnlockPage(page);
+               }
+       }
+       return 0;
+ }
+ static inline void zeromap_pte_range(pte_t * pte, unsigned long address,
+                                      unsigned long size, pgprot_t prot)
+ {
+       unsigned long end;
+       address &= ~PMD_MASK;
+       end = address + size;
+       if (end > PMD_SIZE)
+               end = PMD_SIZE;
+       do {
+               pte_t zero_pte = pte_wrprotect(mk_pte(ZERO_PAGE(address), prot));
+               pte_t oldpage = ptep_get_and_clear(pte);
+               set_pte(pte, zero_pte);
+               forget_pte(oldpage);
+               address += PAGE_SIZE;
+               pte++;
+       } while (address && (address < end));
+ }
+ static inline int zeromap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned long address,
+                                     unsigned long size, pgprot_t prot)
+ {
+       unsigned long end;
+       address &= ~PGDIR_MASK;
+       end = address + size;
+       if (end > PGDIR_SIZE)
+               end = PGDIR_SIZE;
+       do {
+               pte_t * pte = pte_alloc(mm, pmd, address);
+               if (!pte)
+                       return -ENOMEM;
+               zeromap_pte_range(pte, address, end - address, prot);
+               address = (address + PMD_SIZE) & PMD_MASK;
+               pmd++;
+       } while (address && (address < end));
+       return 0;
+ }
+ int zeromap_page_range(unsigned long address, unsigned long size, pgprot_t prot)
+ {
+       int error = 0;
+       pgd_t * dir;
+       unsigned long beg = address;
+       unsigned long end = address + size;
+       struct mm_struct *mm = current->mm;
+       dir = pgd_offset(mm, address);
+       flush_cache_range(mm, beg, end);
+       if (address >= end)
+               BUG();
+       spin_lock(&mm->page_table_lock);
+       do {
+               pmd_t *pmd = pmd_alloc(mm, dir, address);
+               error = -ENOMEM;
+               if (!pmd)
+                       break;
+               error = zeromap_pmd_range(mm, pmd, address, end - address, prot);
+               if (error)
+                       break;
+               address = (address + PGDIR_SIZE) & PGDIR_MASK;
+               dir++;
+       } while (address && (address < end));
+       spin_unlock(&mm->page_table_lock);
+       flush_tlb_range(mm, beg, end);
+       return error;
+ }
+ /*
+  * maps a range of physical memory into the requested pages. the old
+  * mappings are removed. any references to nonexistent pages results
+  * in null mappings (currently treated as "copy-on-access")
+  */
+ static inline void remap_pte_range(pte_t * pte, unsigned long address, unsigned long size,
+       unsigned long phys_addr, pgprot_t prot)
+ {
+       unsigned long end;
+       address &= ~PMD_MASK;
+       end = address + size;
+       if (end > PMD_SIZE)
+               end = PMD_SIZE;
+       do {
+               struct page *page;
+               pte_t oldpage;
+               oldpage = ptep_get_and_clear(pte);
+               page = virt_to_page(__va(phys_addr));
+               if ((!VALID_PAGE(page)) || PageReserved(page))
+                       set_pte(pte, mk_pte_phys(phys_addr, prot));
+               forget_pte(oldpage);
+               address += PAGE_SIZE;
+               phys_addr += PAGE_SIZE;
+               pte++;
+       } while (address && (address < end));
+ }
+ static inline int remap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned long address, unsigned long size,
+       unsigned long phys_addr, pgprot_t prot)
+ {
+       unsigned long end;
+       address &= ~PGDIR_MASK;
+       end = address + size;
+       if (end > PGDIR_SIZE)
+               end = PGDIR_SIZE;
+       phys_addr -= address;
+       do {
+               pte_t * pte = pte_alloc(mm, pmd, address);
+               if (!pte)
+                       return -ENOMEM;
+               remap_pte_range(pte, address, end - address, address + phys_addr, prot);
+               address = (address + PMD_SIZE) & PMD_MASK;
+               pmd++;
+       } while (address && (address < end));
+       return 0;
+ }
+ /*  Note: this is only safe if the mm semaphore is held when called. */
+ int remap_page_range(unsigned long from, unsigned long phys_addr, unsigned long size, pgprot_t prot)
+ {
+       int error = 0;
+       pgd_t * dir;
+       unsigned long beg = from;
+       unsigned long end = from + size;
+       struct mm_struct *mm = current->mm;
+       phys_addr -= from;
+       dir = pgd_offset(mm, from);
+       flush_cache_range(mm, beg, end);
+       if (from >= end)
+               BUG();
+       spin_lock(&mm->page_table_lock);
+       do {
+               pmd_t *pmd = pmd_alloc(mm, dir, from);
+               error = -ENOMEM;
+               if (!pmd)
+                       break;
+               error = remap_pmd_range(mm, pmd, from, end - from, phys_addr + from, prot);
+               if (error)
+                       break;
+               from = (from + PGDIR_SIZE) & PGDIR_MASK;
+               dir++;
+       } while (from && (from < end));
+       spin_unlock(&mm->page_table_lock);
+       flush_tlb_range(mm, beg, end);
+       return error;
+ }
+ /*
+  * Establish a new mapping:
+  *  - flush the old one
+  *  - update the page tables
+  *  - inform the TLB about the new one
+  *
+  * We hold the mm semaphore for reading and vma->vm_mm->page_table_lock
+  */
+ static inline void establish_pte(struct vm_area_struct * vma, unsigned long address, pte_t *page_table, pte_t entry)
+ {
+ #ifdef CONFIG_XEN
+       if ( likely(vma->vm_mm == current->mm) ) {
 -      if ( likely(vma->vm_mm == current->mm) ) {
 -              XEN_flush_page_update_queue();
 -              HYPERVISOR_update_va_mapping(address>>PAGE_SHIFT, pte, 0);
 -      } else {
++              HYPERVISOR_update_va_mapping(address, entry, UVMF_INVLPG|UVMF_LOCAL);
+       } else {
+               set_pte(page_table, entry);
+               flush_tlb_page(vma, address);
+       }
+ #else
+       set_pte(page_table, entry);
+       flush_tlb_page(vma, address);
+ #endif
+       update_mmu_cache(vma, address, entry);
+ }
+ /*
+  * We hold the mm semaphore for reading and vma->vm_mm->page_table_lock
+  */
+ static inline void break_cow(struct vm_area_struct * vma, struct page * new_page, unsigned long address, 
+               pte_t *page_table)
+ {
+       flush_page_to_ram(new_page);
+       flush_cache_page(vma, address);
+       establish_pte(vma, address, page_table, pte_mkwrite(pte_mkdirty(mk_pte(new_page, vma->vm_page_prot))));
+ }
+ /*
+  * This routine handles present pages, when users try to write
+  * to a shared page. It is done by copying the page to a new address
+  * and decrementing the shared-page counter for the old page.
+  *
+  * Goto-purists beware: the only reason for goto's here is that it results
+  * in better assembly code.. The "default" path will see no jumps at all.
+  *
+  * Note that this routine assumes that the protection checks have been
+  * done by the caller (the low-level page fault routine in most cases).
+  * Thus we can safely just mark it writable once we've done any necessary
+  * COW.
+  *
+  * We also mark the page dirty at this point even though the page will
+  * change only once the write actually happens. This avoids a few races,
+  * and potentially makes it more efficient.
+  *
+  * We hold the mm semaphore and the page_table_lock on entry and exit
+  * with the page_table_lock released.
+  */
+ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma,
+       unsigned long address, pte_t *page_table, pte_t pte)
+ {
+       struct page *old_page, *new_page;
+       old_page = pte_page(pte);
+       if (!VALID_PAGE(old_page))
+               goto bad_wp_page;
+       if (!TryLockPage(old_page)) {
+               int reuse = can_share_swap_page(old_page);
+               unlock_page(old_page);
+               if (reuse) {
+                       flush_cache_page(vma, address);
+                       establish_pte(vma, address, page_table, pte_mkyoung(pte_mkdirty(pte_mkwrite(pte))));
+                       spin_unlock(&mm->page_table_lock);
+                       return 1;       /* Minor fault */
+               }
+       }
+       /*
+        * Ok, we need to copy. Oh, well..
+        */
+       page_cache_get(old_page);
+       spin_unlock(&mm->page_table_lock);
+       new_page = alloc_page(GFP_HIGHUSER);
+       if (!new_page)
+               goto no_mem;
+       copy_cow_page(old_page,new_page,address);
+       /*
+        * Re-check the pte - we dropped the lock
+        */
+       spin_lock(&mm->page_table_lock);
+       if (pte_same(*page_table, pte)) {
+               if (PageReserved(old_page))
+                       ++mm->rss;
+               break_cow(vma, new_page, address, page_table);
+               if (vm_anon_lru)
+                       lru_cache_add(new_page);
+               /* Free the old page.. */
+               new_page = old_page;
+       }
+       spin_unlock(&mm->page_table_lock);
+       page_cache_release(new_page);
+       page_cache_release(old_page);
+       return 1;       /* Minor fault */
+ bad_wp_page:
+       spin_unlock(&mm->page_table_lock);
+       printk("do_wp_page: bogus page at address %08lx (page 0x%lx)\n",address,(unsigned long)old_page);
+       return -1;
+ no_mem:
+       page_cache_release(old_page);
+       return -1;
+ }
+ static void vmtruncate_list(struct vm_area_struct *mpnt, unsigned long pgoff)
+ {
+       do {
+               struct mm_struct *mm = mpnt->vm_mm;
+               unsigned long start = mpnt->vm_start;
+               unsigned long end = mpnt->vm_end;
+               unsigned long len = end - start;
+               unsigned long diff;
+               /* mapping wholly truncated? */
+               if (mpnt->vm_pgoff >= pgoff) {
+                       zap_page_range(mm, start, len);
+                       continue;
+               }
+               /* mapping wholly unaffected? */
+               len = len >> PAGE_SHIFT;
+               diff = pgoff - mpnt->vm_pgoff;
+               if (diff >= len)
+                       continue;
+               /* Ok, partially affected.. */
+               start += diff << PAGE_SHIFT;
+               len = (len - diff) << PAGE_SHIFT;
+               zap_page_range(mm, start, len);
+       } while ((mpnt = mpnt->vm_next_share) != NULL);
+ }
+ /*
+  * Handle all mappings that got truncated by a "truncate()"
+  * system call.
+  *
+  * NOTE! We have to be ready to update the memory sharing
+  * between the file and the memory map for a potential last
+  * incomplete page.  Ugly, but necessary.
+  */
+ int vmtruncate(struct inode * inode, loff_t offset)
+ {
+       unsigned long pgoff;
+       struct address_space *mapping = inode->i_mapping;
+       unsigned long limit;
+       if (inode->i_size < offset)
+               goto do_expand;
+       inode->i_size = offset;
+       spin_lock(&mapping->i_shared_lock);
+       if (!mapping->i_mmap && !mapping->i_mmap_shared)
+               goto out_unlock;
+       pgoff = (offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+       if (mapping->i_mmap != NULL)
+               vmtruncate_list(mapping->i_mmap, pgoff);
+       if (mapping->i_mmap_shared != NULL)
+               vmtruncate_list(mapping->i_mmap_shared, pgoff);
+ out_unlock:
+       spin_unlock(&mapping->i_shared_lock);
+       truncate_inode_pages(mapping, offset);
+       goto out_truncate;
+ do_expand:
+       limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
+       if (limit != RLIM_INFINITY && offset > limit)
+               goto out_sig;
+       if (offset > inode->i_sb->s_maxbytes)
+               goto out;
+       inode->i_size = offset;
+ out_truncate:
+       if (inode->i_op && inode->i_op->truncate) {
+               lock_kernel();
+               inode->i_op->truncate(inode);
+               unlock_kernel();
+       }
+       return 0;
+ out_sig:
+       send_sig(SIGXFSZ, current, 0);
+ out:
+       return -EFBIG;
+ }
+ /* 
+  * Primitive swap readahead code. We simply read an aligned block of
+  * (1 << page_cluster) entries in the swap area. This method is chosen
+  * because it doesn't cost us any seek time.  We also make sure to queue
+  * the 'original' request together with the readahead ones...  
+  */
+ void swapin_readahead(swp_entry_t entry)
+ {
+       int i, num;
+       struct page *new_page;
+       unsigned long offset;
+       /*
+        * Get the number of handles we should do readahead io to.
+        */
+       num = valid_swaphandles(entry, &offset);
+       for (i = 0; i < num; offset++, i++) {
+               /* Ok, do the async read-ahead now */
+               new_page = read_swap_cache_async(SWP_ENTRY(SWP_TYPE(entry), offset));
+               if (!new_page)
+                       break;
+               page_cache_release(new_page);
+       }
+       return;
+ }
+ /*
+  * We hold the mm semaphore and the page_table_lock on entry and
+  * should release the pagetable lock on exit..
+  */
+ static int do_swap_page(struct mm_struct * mm,
+       struct vm_area_struct * vma, unsigned long address,
+       pte_t * page_table, pte_t orig_pte, int write_access)
+ {
+       struct page *page;
+       swp_entry_t entry = pte_to_swp_entry(orig_pte);
+       pte_t pte;
+       int ret = 1;
+       spin_unlock(&mm->page_table_lock);
+       page = lookup_swap_cache(entry);
+       if (!page) {
+               swapin_readahead(entry);
+               page = read_swap_cache_async(entry);
+               if (!page) {
+                       /*
+                        * Back out if somebody else faulted in this pte while
+                        * we released the page table lock.
+                        */
+                       int retval;
+                       spin_lock(&mm->page_table_lock);
+                       retval = pte_same(*page_table, orig_pte) ? -1 : 1;
+                       spin_unlock(&mm->page_table_lock);
+                       return retval;
+               }
+               /* Had to read the page from swap area: Major fault */
+               ret = 2;
+       }
+       mark_page_accessed(page);
+       lock_page(page);
+       /*
+        * Back out if somebody else faulted in this pte while we
+        * released the page table lock.
+        */
+       spin_lock(&mm->page_table_lock);
+       if (!pte_same(*page_table, orig_pte)) {
+               spin_unlock(&mm->page_table_lock);
+               unlock_page(page);
+               page_cache_release(page);
+               return 1;
+       }
+       /* The page isn't present yet, go ahead with the fault. */
+               
+       swap_free(entry);
+       if (vm_swap_full())
+               remove_exclusive_swap_page(page);
+       mm->rss++;
+       pte = mk_pte(page, vma->vm_page_prot);
+       if (write_access && can_share_swap_page(page))
+               pte = pte_mkdirty(pte_mkwrite(pte));
+       unlock_page(page);
+       flush_page_to_ram(page);
+       flush_icache_page(vma, page);
+ #ifdef CONFIG_XEN
 -              XEN_flush_page_update_queue();
 -      }
++      if ( likely(vma->vm_mm == current->mm) )
++              HYPERVISOR_update_va_mapping(address, pte, 0);
++      else
+               set_pte(page_table, pte);
 -      if ( likely(vma->vm_mm == current->mm) ) {
 -              XEN_flush_page_update_queue();
 -              HYPERVISOR_update_va_mapping(addr>>PAGE_SHIFT, entry, 0);
 -      } else {
+ #else
+       set_pte(page_table, pte);
+ #endif
+       /* No need to invalidate - it was non-present before */
+       update_mmu_cache(vma, address, pte);
+       spin_unlock(&mm->page_table_lock);
+       return ret;
+ }
+ /*
+  * We are called with the MM semaphore and page_table_lock
+  * spinlock held to protect against concurrent faults in
+  * multithreaded programs. 
+  */
+ static int do_anonymous_page(struct mm_struct * mm, struct vm_area_struct * vma, pte_t *page_table, int write_access, unsigned long addr)
+ {
+       pte_t entry;
+       /* Read-only mapping of ZERO_PAGE. */
+       entry = pte_wrprotect(mk_pte(ZERO_PAGE(addr), vma->vm_page_prot));
+       /* ..except if it's a write access */
+       if (write_access) {
+               struct page *page;
+               /* Allocate our own private page. */
+               spin_unlock(&mm->page_table_lock);
+               page = alloc_page(GFP_HIGHUSER);
+               if (!page)
+                       goto no_mem;
+               clear_user_highpage(page, addr);
+               spin_lock(&mm->page_table_lock);
+               if (!pte_none(*page_table)) {
+                       page_cache_release(page);
+                       spin_unlock(&mm->page_table_lock);
+                       return 1;
+               }
+               mm->rss++;
+               flush_page_to_ram(page);
+               entry = pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
+               if (vm_anon_lru)
+                       lru_cache_add(page);
+               mark_page_accessed(page);
+       }
+ #ifdef CONFIG_XEN
 -              XEN_flush_page_update_queue();
 -      }
++      if ( likely(vma->vm_mm == current->mm) )
++              HYPERVISOR_update_va_mapping(addr, entry, 0);
++      else
+               set_pte(page_table, entry);
 -              if ( likely(vma->vm_mm == current->mm) ) {
 -                      XEN_flush_page_update_queue();
 -                      HYPERVISOR_update_va_mapping(address>>PAGE_SHIFT, entry, 0);
 -              } else {
+ #else
+       set_pte(page_table, entry);
+ #endif
+       /* No need to invalidate - it was non-present before */
+       update_mmu_cache(vma, addr, entry);
+       spin_unlock(&mm->page_table_lock);
+       return 1;       /* Minor fault */
+ no_mem:
+       return -1;
+ }
+ /*
+  * do_no_page() tries to create a new page mapping. It aggressively
+  * tries to share with existing pages, but makes a separate copy if
+  * the "write_access" parameter is true in order to avoid the next
+  * page fault.
+  *
+  * As this is called only for pages that do not currently exist, we
+  * do not need to flush old virtual caches or the TLB.
+  *
+  * This is called with the MM semaphore held and the page table
+  * spinlock held. Exit with the spinlock released.
+  */
+ static int do_no_page(struct mm_struct * mm, struct vm_area_struct * vma,
+       unsigned long address, int write_access, pte_t *page_table)
+ {
+       struct page * new_page;
+       pte_t entry;
+       if (!vma->vm_ops || !vma->vm_ops->nopage)
+               return do_anonymous_page(mm, vma, page_table, write_access, address);
+       spin_unlock(&mm->page_table_lock);
+       new_page = vma->vm_ops->nopage(vma, address & PAGE_MASK, 0);
+       if (new_page == NULL)   /* no page was available -- SIGBUS */
+               return 0;
+       if (new_page == NOPAGE_OOM)
+               return -1;
+       /*
+        * Should we do an early C-O-W break?
+        */
+       if (write_access && !(vma->vm_flags & VM_SHARED)) {
+               struct page * page = alloc_page(GFP_HIGHUSER);
+               if (!page) {
+                       page_cache_release(new_page);
+                       return -1;
+               }
+               copy_user_highpage(page, new_page, address);
+               page_cache_release(new_page);
+               if (vm_anon_lru)
+                       lru_cache_add(page);
+               new_page = page;
+       }
+       spin_lock(&mm->page_table_lock);
+       /*
+        * This silly early PAGE_DIRTY setting removes a race
+        * due to the bad i386 page protection. But it's valid
+        * for other architectures too.
+        *
+        * Note that if write_access is true, we either now have
+        * an exclusive copy of the page, or this is a shared mapping,
+        * so we can make it writable and dirty to avoid having to
+        * handle that later.
+        */
+       /* Only go through if we didn't race with anybody else... */
+       if (pte_none(*page_table)) {
+               if (!PageReserved(new_page))
+                       ++mm->rss;
+               flush_page_to_ram(new_page);
+               flush_icache_page(vma, new_page);
+               entry = mk_pte(new_page, vma->vm_page_prot);
+               if (write_access)
+                       entry = pte_mkwrite(pte_mkdirty(entry));
+ #ifdef CONFIG_XEN
 -                      XEN_flush_page_update_queue();
 -              }
++              if ( likely(vma->vm_mm == current->mm) )
++                      HYPERVISOR_update_va_mapping(address, entry, 0);
++              else
+                       set_pte(page_table, entry);
 -                      XEN_flush_page_update_queue();
+ #else
+               set_pte(page_table, entry);
+ #endif
+       } else {
+               /* One of our sibling threads was faster, back out. */
+               page_cache_release(new_page);
+               spin_unlock(&mm->page_table_lock);
+               return 1;
+       }
+       /* no need to invalidate: a not-present page shouldn't be cached */
+       update_mmu_cache(vma, address, entry);
+       spin_unlock(&mm->page_table_lock);
+       return 2;       /* Major fault */
+ }
+ /*
+  * These routines also need to handle stuff like marking pages dirty
+  * and/or accessed for architectures that don't do it in hardware (most
+  * RISC architectures).  The early dirtying is also good on the i386.
+  *
+  * There is also a hook called "update_mmu_cache()" that architectures
+  * with external mmu caches can use to update those (ie the Sparc or
+  * PowerPC hashed page tables that act as extended TLBs).
+  *
+  * Note the "page_table_lock". It is to protect against kswapd removing
+  * pages from under us. Note that kswapd only ever _removes_ pages, never
+  * adds them. As such, once we have noticed that the page is not present,
+  * we can drop the lock early.
+  *
+  * The adding of pages is protected by the MM semaphore (which we hold),
+  * so we don't need to worry about a page being suddenly been added into
+  * our VM.
+  *
+  * We enter with the pagetable spinlock held, we are supposed to
+  * release it when done.
+  */
+ static inline int handle_pte_fault(struct mm_struct *mm,
+       struct vm_area_struct * vma, unsigned long address,
+       int write_access, pte_t * pte)
+ {
+       pte_t entry;
+       entry = *pte;
+       if (!pte_present(entry)) {
+               /*
+                * If it truly wasn't present, we know that kswapd
+                * and the PTE updates will not touch it later. So
+                * drop the lock.
+                */
+               if (pte_none(entry))
+                       return do_no_page(mm, vma, address, write_access, pte);
+               return do_swap_page(mm, vma, address, pte, entry, write_access);
+       }
+       if (write_access) {
+               if (!pte_write(entry))
+                       return do_wp_page(mm, vma, address, pte, entry);
+               entry = pte_mkdirty(entry);
+       }
+       entry = pte_mkyoung(entry);
+       establish_pte(vma, address, pte, entry);
+       spin_unlock(&mm->page_table_lock);
+       return 1;
+ }
+ /*
+  * By the time we get here, we already hold the mm semaphore
+  */
+ int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct * vma,
+       unsigned long address, int write_access)
+ {
+       pgd_t *pgd;
+       pmd_t *pmd;
+       current->state = TASK_RUNNING;
+       pgd = pgd_offset(mm, address);
+       /*
+        * We need the page table lock to synchronize with kswapd
+        * and the SMP-safe atomic PTE updates.
+        */
+       spin_lock(&mm->page_table_lock);
+       pmd = pmd_alloc(mm, pgd, address);
+       if (pmd) {
+               pte_t * pte = pte_alloc(mm, pmd, address);
+               if (pte)
+                       return handle_pte_fault(mm, vma, address, write_access, pte);
+       }
+       spin_unlock(&mm->page_table_lock);
+       return -1;
+ }
+ /*
+  * Allocate page middle directory.
+  *
+  * We've already handled the fast-path in-line, and we own the
+  * page table lock.
+  *
+  * On a two-level page table, this ends up actually being entirely
+  * optimized away.
+  */
+ pmd_t fastcall *__pmd_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address)
+ {
+       pmd_t *new;
+       /* "fast" allocation can happen without dropping the lock.. */
+       new = pmd_alloc_one_fast(mm, address);
+       if (!new) {
+               spin_unlock(&mm->page_table_lock);
+               new = pmd_alloc_one(mm, address);
+               spin_lock(&mm->page_table_lock);
+               if (!new)
+                       return NULL;
+               /*
+                * Because we dropped the lock, we should re-check the
+                * entry, as somebody else could have populated it..
+                */
+               if (!pgd_none(*pgd)) {
+                       pmd_free(new);
+                       check_pgt_cache();
+                       goto out;
+               }
+       }
+       pgd_populate(mm, pgd, new);
+ out:
+       return pmd_offset(pgd, address);
+ }
+ /*
+  * Allocate the page table directory.
+  *
+  * We've already handled the fast-path in-line, and we own the
+  * page table lock.
+  */
+ pte_t fastcall *pte_alloc(struct mm_struct *mm, pmd_t *pmd, unsigned long address)
+ {
+       if (pmd_none(*pmd)) {
+               pte_t *new;
+               /* "fast" allocation can happen without dropping the lock.. */
+               new = pte_alloc_one_fast(mm, address);
+               if (!new) {
+                       spin_unlock(&mm->page_table_lock);
+                       new = pte_alloc_one(mm, address);
+                       spin_lock(&mm->page_table_lock);
+                       if (!new)
+                               return NULL;
+                       /*
+                        * Because we dropped the lock, we should re-check the
+                        * entry, as somebody else could have populated it..
+                        */
+                       if (!pmd_none(*pmd)) {
+                               pte_free(new);
+                               check_pgt_cache();
+                               goto out;
+                       }
+               }
+               pmd_populate(mm, pmd, new);
+       }
+ out:
+       return pte_offset(pmd, address);
+ }
+ int make_pages_present(unsigned long addr, unsigned long end)
+ {
+       int ret, len, write;
+       struct vm_area_struct * vma;
+       vma = find_vma(current->mm, addr);
+       write = (vma->vm_flags & VM_WRITE) != 0;
+       if (addr >= end)
+               BUG();
+       if (end > vma->vm_end)
+               BUG();
+       len = (end+PAGE_SIZE-1)/PAGE_SIZE-addr/PAGE_SIZE;
+       ret = get_user_pages(current, current->mm, addr,
+                       len, write, 0, NULL, NULL);
+       return ret == len ? 0 : -1;
+ }
+ struct page * vmalloc_to_page(void * vmalloc_addr)
+ {
+       unsigned long addr = (unsigned long) vmalloc_addr;
+       struct page *page = NULL;
+       pmd_t *pmd;
+       pte_t *pte;
+       pgd_t *pgd;
+       
+       pgd = pgd_offset_k(addr);
+       if (!pgd_none(*pgd)) {
+               pmd = pmd_offset(pgd, addr);
+               if (!pmd_none(*pmd)) {
+                       pte = pte_offset(pmd, addr);
+                       if (pte_present(*pte)) {
+                               page = pte_page(*pte);
+                       }
+               }
+       }
+       return page;
+ }
index 0000000000000000000000000000000000000000,330e194baed1bc972c0e31bb2bf3daf4d7a62337..475c308b1b6bbecb9af4161bd84ccbdec58f5dc4
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,392 +1,390 @@@
 -      XEN_flush_page_update_queue();
+ /*
+  *    linux/mm/remap.c
+  *
+  *    (C) Copyright 1996 Linus Torvalds
+  */
+ #include <linux/slab.h>
+ #include <linux/smp_lock.h>
+ #include <linux/shm.h>
+ #include <linux/mman.h>
+ #include <linux/swap.h>
+ #include <asm/uaccess.h>
+ #include <asm/pgalloc.h>
+ extern int vm_enough_memory(long pages);
+ static inline pte_t *get_one_pte(struct mm_struct *mm, unsigned long addr)
+ {
+       pgd_t * pgd;
+       pmd_t * pmd;
+       pte_t * pte = NULL;
+       pgd = pgd_offset(mm, addr);
+       if (pgd_none(*pgd))
+               goto end;
+       if (pgd_bad(*pgd)) {
+               pgd_ERROR(*pgd);
+               pgd_clear(pgd);
+               goto end;
+       }
+       pmd = pmd_offset(pgd, addr);
+       if (pmd_none(*pmd))
+               goto end;
+       if (pmd_bad(*pmd)) {
+               pmd_ERROR(*pmd);
+               pmd_clear(pmd);
+               goto end;
+       }
+       pte = pte_offset(pmd, addr);
+       if (pte_none(*pte))
+               pte = NULL;
+ end:
+       return pte;
+ }
+ static inline pte_t *alloc_one_pte(struct mm_struct *mm, unsigned long addr)
+ {
+       pmd_t * pmd;
+       pte_t * pte = NULL;
+       pmd = pmd_alloc(mm, pgd_offset(mm, addr), addr);
+       if (pmd)
+               pte = pte_alloc(mm, pmd, addr);
+       return pte;
+ }
+ static inline int copy_one_pte(struct mm_struct *mm, pte_t * src, pte_t * dst)
+ {
+       int error = 0;
+       pte_t pte;
+       if (!pte_none(*src)) {
+               pte = ptep_get_and_clear(src);
+               if (!dst) {
+                       /* No dest?  We must put it back. */
+                       dst = src;
+                       error++;
+               }
+               set_pte(dst, pte);
+       }
+       return error;
+ }
+ static int move_one_page(struct mm_struct *mm, unsigned long old_addr, unsigned long new_addr)
+ {
+       int error = 0;
+       pte_t * src, * dst;
+       spin_lock(&mm->page_table_lock);
+       src = get_one_pte(mm, old_addr);
+       if (src) {
+               dst = alloc_one_pte(mm, new_addr);
+               src = get_one_pte(mm, old_addr);
+               if (src) 
+                       error = copy_one_pte(mm, src, dst);
+       }
+       spin_unlock(&mm->page_table_lock);
+       return error;
+ }
+ static int move_page_tables(struct mm_struct * mm,
+       unsigned long new_addr, unsigned long old_addr, unsigned long len)
+ {
+       unsigned long offset = len;
+       flush_cache_range(mm, old_addr, old_addr + len);
+       /*
+        * This is not the clever way to do this, but we're taking the
+        * easy way out on the assumption that most remappings will be
+        * only a few pages.. This also makes error recovery easier.
+        */
+       while (offset) {
+               offset -= PAGE_SIZE;
+               if (move_one_page(mm, old_addr + offset, new_addr + offset))
+                       goto oops_we_failed;
+       }
+       flush_tlb_range(mm, old_addr, old_addr + len);
+       return 0;
+       /*
+        * Ok, the move failed because we didn't have enough pages for
+        * the new page table tree. This is unlikely, but we have to
+        * take the possibility into account. In that case we just move
+        * all the pages back (this will work, because we still have
+        * the old page tables)
+        */
+ oops_we_failed:
 -      XEN_flush_page_update_queue();
+       flush_cache_range(mm, new_addr, new_addr + len);
+       while ((offset += PAGE_SIZE) < len)
+               move_one_page(mm, new_addr + offset, old_addr + offset);
+       zap_page_range(mm, new_addr, len);
+       return -1;
+ }
+ static inline unsigned long move_vma(struct vm_area_struct * vma,
+       unsigned long addr, unsigned long old_len, unsigned long new_len,
+       unsigned long new_addr)
+ {
+       struct mm_struct * mm = vma->vm_mm;
+       struct vm_area_struct * new_vma, * next, * prev;
+       int allocated_vma;
+       new_vma = NULL;
+       next = find_vma_prev(mm, new_addr, &prev);
+       if (next) {
+               if (prev && prev->vm_end == new_addr &&
+                   can_vma_merge(prev, vma->vm_flags) && !vma->vm_file && !(vma->vm_flags & VM_SHARED)) {
+                       spin_lock(&mm->page_table_lock);
+                       prev->vm_end = new_addr + new_len;
+                       spin_unlock(&mm->page_table_lock);
+                       new_vma = prev;
+                       if (next != prev->vm_next)
+                               BUG();
+                       if (prev->vm_end == next->vm_start && can_vma_merge(next, prev->vm_flags)) {
+                               spin_lock(&mm->page_table_lock);
+                               prev->vm_end = next->vm_end;
+                               __vma_unlink(mm, next, prev);
+                               spin_unlock(&mm->page_table_lock);
+                               mm->map_count--;
+                               kmem_cache_free(vm_area_cachep, next);
+                       }
+               } else if (next->vm_start == new_addr + new_len &&
+                          can_vma_merge(next, vma->vm_flags) && !vma->vm_file && !(vma->vm_flags & VM_SHARED)) {
+                       spin_lock(&mm->page_table_lock);
+                       next->vm_start = new_addr;
+                       spin_unlock(&mm->page_table_lock);
+                       new_vma = next;
+               }
+       } else {
+               prev = find_vma(mm, new_addr-1);
+               if (prev && prev->vm_end == new_addr &&
+                   can_vma_merge(prev, vma->vm_flags) && !vma->vm_file && !(vma->vm_flags & VM_SHARED)) {
+                       spin_lock(&mm->page_table_lock);
+                       prev->vm_end = new_addr + new_len;
+                       spin_unlock(&mm->page_table_lock);
+                       new_vma = prev;
+               }
+       }
+       allocated_vma = 0;
+       if (!new_vma) {
+               new_vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
+               if (!new_vma)
+                       goto out;
+               allocated_vma = 1;
+       }
+       if (!move_page_tables(current->mm, new_addr, addr, old_len)) {
+               unsigned long vm_locked = vma->vm_flags & VM_LOCKED;
+               if (allocated_vma) {
+                       *new_vma = *vma;
+                       new_vma->vm_start = new_addr;
+                       new_vma->vm_end = new_addr+new_len;
+                       new_vma->vm_pgoff += (addr-vma->vm_start) >> PAGE_SHIFT;
+                       new_vma->vm_raend = 0;
+                       if (new_vma->vm_file)
+                               get_file(new_vma->vm_file);
+                       if (new_vma->vm_ops && new_vma->vm_ops->open)
+                               new_vma->vm_ops->open(new_vma);
+                       insert_vm_struct(current->mm, new_vma);
+               }
+               /* XXX: possible errors masked, mapping might remain */
+               do_munmap(current->mm, addr, old_len);
+               current->mm->total_vm += new_len >> PAGE_SHIFT;
+               if (vm_locked) {
+                       current->mm->locked_vm += new_len >> PAGE_SHIFT;
+                       if (new_len > old_len)
+                               make_pages_present(new_addr + old_len,
+                                                  new_addr + new_len);
+               }
+               return new_addr;
+       }
+       if (allocated_vma)
+               kmem_cache_free(vm_area_cachep, new_vma);
+  out:
+       return -ENOMEM;
+ }
+ /*
+  * Expand (or shrink) an existing mapping, potentially moving it at the
+  * same time (controlled by the MREMAP_MAYMOVE flag and available VM space)
+  *
+  * MREMAP_FIXED option added 5-Dec-1999 by Benjamin LaHaise
+  * This option implies MREMAP_MAYMOVE.
+  */
+ unsigned long do_mremap(unsigned long addr,
+       unsigned long old_len, unsigned long new_len,
+       unsigned long flags, unsigned long new_addr)
+ {
+       struct vm_area_struct *vma;
+       unsigned long ret = -EINVAL;
+       if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
+               goto out;
+       if (addr & ~PAGE_MASK)
+               goto out;
+       old_len = PAGE_ALIGN(old_len);
+       new_len = PAGE_ALIGN(new_len);
+       if (old_len > TASK_SIZE || addr > TASK_SIZE - old_len)
+               goto out;
+       if (addr >= TASK_SIZE)
+               goto out;
+       /* new_addr is only valid if MREMAP_FIXED is specified */
+       if (flags & MREMAP_FIXED) {
+               if (new_addr & ~PAGE_MASK)
+                       goto out;
+               if (!(flags & MREMAP_MAYMOVE))
+                       goto out;
+               if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
+                       goto out;
+               if (new_addr >= TASK_SIZE)
+                       goto out;
+               /*
+                * Allow new_len == 0 only if new_addr == addr
+                * to preserve truncation in place (that was working
+                * safe and some app may depend on it).
+                */
+               if (unlikely(!new_len && new_addr != addr))
+                       goto out;
+               /* Check if the location we're moving into overlaps the
+                * old location at all, and fail if it does.
+                */
+               if ((new_addr <= addr) && (new_addr+new_len) > addr)
+                       goto out;
+               if ((addr <= new_addr) && (addr+old_len) > new_addr)
+                       goto out;
+               ret = do_munmap(current->mm, new_addr, new_len);
+               if (ret && new_len)
+                       goto out;
+       }
+       /*
+        * Always allow a shrinking remap: that just unmaps
+        * the unnecessary pages..
+        */
+       if (old_len >= new_len) {
+               ret = do_munmap(current->mm, addr+new_len, old_len - new_len);
+               if (ret && old_len != new_len)
+                       goto out;
+               ret = addr;
+               if (!(flags & MREMAP_FIXED) || (new_addr == addr))
+                       goto out;
+       }
+       /*
+        * Ok, we need to grow..  or relocate.
+        */
+       ret = -EFAULT;
+       vma = find_vma(current->mm, addr);
+       if (!vma || vma->vm_start > addr)
+               goto out;
+       /* We can't remap across vm area boundaries */
+       if (old_len > vma->vm_end - addr)
+               goto out;
+       if (vma->vm_flags & VM_DONTEXPAND) {
+               if (new_len > old_len)
+                       goto out;
+       }
+       if (vma->vm_flags & VM_LOCKED) {
+               unsigned long locked = current->mm->locked_vm << PAGE_SHIFT;
+               locked += new_len - old_len;
+               ret = -EAGAIN;
+               if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
+                       goto out;
+       }
+       ret = -ENOMEM;
+       if ((current->mm->total_vm << PAGE_SHIFT) + (new_len - old_len)
+           > current->rlim[RLIMIT_AS].rlim_cur)
+               goto out;
+       /* Private writable mapping? Check memory availability.. */
+       if ((vma->vm_flags & (VM_SHARED | VM_WRITE)) == VM_WRITE &&
+           !(flags & MAP_NORESERVE)                             &&
+           !vm_enough_memory((new_len - old_len) >> PAGE_SHIFT))
+               goto out;
+ #if defined(CONFIG_XEN_PRIVILEGED_GUEST)
+       /* mremap() unsupported for I/O mappings in Xenolinux. */
+       ret = -EINVAL;
+       if (vma->vm_flags & VM_IO)
+               goto out;
+ #endif
+       /* old_len exactly to the end of the area..
+        * And we're not relocating the area.
+        */
+       if (old_len == vma->vm_end - addr &&
+           !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
+           (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
+               unsigned long max_addr = TASK_SIZE;
+               if (vma->vm_next)
+                       max_addr = vma->vm_next->vm_start;
+               /* can we just expand the current mapping? */
+               if (max_addr - addr >= new_len) {
+                       int pages = (new_len - old_len) >> PAGE_SHIFT;
+                       spin_lock(&vma->vm_mm->page_table_lock);
+                       vma->vm_end = addr + new_len;
+                       spin_unlock(&vma->vm_mm->page_table_lock);
+                       current->mm->total_vm += pages;
+                       if (vma->vm_flags & VM_LOCKED) {
+                               current->mm->locked_vm += pages;
+                               make_pages_present(addr + old_len,
+                                                  addr + new_len);
+                       }
+                       ret = addr;
+                       goto out;
+               }
+       }
+       /*
+        * We weren't able to just expand or shrink the area,
+        * we need to create a new one and move it..
+        */
+       ret = -ENOMEM;
+       if (flags & MREMAP_MAYMOVE) {
+               if (!(flags & MREMAP_FIXED)) {
+                       unsigned long map_flags = 0;
+                       if (vma->vm_flags & VM_SHARED)
+                               map_flags |= MAP_SHARED;
+                       new_addr = get_unmapped_area(vma->vm_file, 0, new_len, vma->vm_pgoff, map_flags);
+                       ret = new_addr;
+                       if (new_addr & ~PAGE_MASK)
+                               goto out;
+               }
+               ret = move_vma(vma, addr, old_len, new_len, new_addr);
+       }
+ out:
+       return ret;
+ }
+ asmlinkage unsigned long sys_mremap(unsigned long addr,
+       unsigned long old_len, unsigned long new_len,
+       unsigned long flags, unsigned long new_addr)
+ {
+       unsigned long ret;
+       down_write(&current->mm->mmap_sem);
+       ret = do_mremap(addr, old_len, new_len, flags, new_addr);
+       up_write(&current->mm->mmap_sem);
+       return ret;
+ }